關於SingleThreadExecutor以及FinalizableDelegatedExecutorService
Executors.newSingleThreadExecutor方法用於創建只用單個線程處理任務的線程池,此方法是一個靜態方法,具體代碼如下
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
從代碼中實例化線程池的部分可以看出它是一個線程數量默認大小和最大大小都爲1的線程池
new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>())new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>())
跟 Executors.newFixedThreadPool(1) 差不多的效果。
然而newFixedThreadPool不一樣的是newSingleThreadExecutor創建的線程池又被一個FinalizableDelegatedExecutorService包裝了一下,如果不看FinalizableDelegatedExecutorService中的源代碼會讓人不明白在這是幹啥用的。
FinalizableDelegatedExecutorService的代碼如下
static class FinalizableDelegatedExecutorService
extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
protected void finalize() {
super.shutdown();
}
}
它很簡單, 只是繼承了DelegatedExecutorService類並增加了一個finalize方法,finalize方法會在虛擬機利用垃圾回收清理對象時被調用,換言之,FinalizableDelegatedExecutorService的實例即使不手動調用shutdown方法關閉現稱池,虛擬機也會幫你完成此任務,不過從嚴謹的角度出發,我們還是應該手動調用shutdown方法,畢竟Java的finalize不是C++的析構函數,必定會被調用,Java虛擬機不保證finalize一定能被正確調用,因此我們不應該依賴於它。
再來看看DelegatedExecutorService,源代碼如下
static class DelegatedExecutorService extends AbstractExecutorService {
private final ExecutorService e;
DelegatedExecutorService(ExecutorService executor) { e = executor; }
public void execute(Runnable command) { e.execute(command); }
public void shutdown() { e.shutdown(); }
public List<Runnable> shutdownNow() { return e.shutdownNow(); }
public boolean isShutdown() { return e.isShutdown(); }
public boolean isTerminated() { return e.isTerminated(); }
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
return e.awaitTermination(timeout, unit);
}
public Future<?> submit(Runnable task) {
return e.submit(task);
}
public <T> Future<T> submit(Callable<T> task) {
return e.submit(task);
}
public <T> Future<T> submit(Runnable task, T result) {
return e.submit(task, result);
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
return e.invokeAll(tasks);
}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
return e.invokeAll(tasks, timeout, unit);
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException {
return e.invokeAny(tasks);
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return e.invokeAny(tasks, timeout, unit);
}
}
它也是一個線程池,確切的說是線程池的一個代理模式的實現,對它所有方法的調用其實是被委託到它持有的目標線程池上,不過它的功能是被閹割的, 因爲他只實現並委託了部分方法,真實線程池存在的那些未被委託的方法在這裏將無法使用。
綜上所述newSingleThreadExecutor創建的線程池是一個
- 單線任務處理的線程池
- shutdown方法必然會被調用
- 不具備ThreadPoolExecutor所有功能的線程池