兩種工廠方法區別
ThreadPoolExecutor是Executors類的底層實現,在JDK幫助文檔中,有如此一段話:“強烈建議程序員使用較爲方便的 Executors 工廠方法 Executors.newCachedThreadPool()(無界線程池,可以進行自動線程回收)、Executors.newFixedThreadPool(int)(固定大小線程池)和Executors.newSingleThreadExecutor()(單個後臺線程),它們均爲大多數使用場景預定義了設置。”
看了一下Executors.newFixedThreadPool(int)和Executors.newSingleThreadExecutor()的源碼:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
發現newSingleThreadExecutor()與newFixedThreadPool(1)的區別就是newSingleThreadExecutor()是被FinalizableDelegatedExecutorService包裝了一下,FinalizableDelegatedExecutorService的代碼如下:
static class FinalizableDelegatedExecutorService
extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
protected void finalize() {
super.shutdown();
}
}
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);
}
}
它是線程池的一個代理模式的實現,對線程池所有方法的調用其實是被到了委託類上,不過委託的功能是被閹割的, 因爲只實現並委託了部分方法,真實線程池存在的那些未被委託的方法在這裏將無法使用。那麼這樣的目的是什麼呢?JDK的源碼註釋是這麼寫的:
Unlike the otherwise equivalent {@code newFixedThreadPool(1)} the returned executor is guaranteed not to be reconfigurable to use additional threads
意思是 newSingleThreadExecutor 不能通過重新配置加入線程,即:
final ExecutorService single = Executors.newSingleThreadExecutor();
ThreadPoolExecutor executor = (ThreadPoolExecutor) single;
// 報錯
executor.setCorePoolSize(5);
這樣就無法在創建了newSingleThreadExecutor以後再把它重新設置爲多線程池,保證了單線程池一旦被創建就永遠只能爲單線程。
參考
https://my.oschina.net/weiweiblog/blog/484543
https://www.jianshu.com/p/2b7d853322bb
https://segmentfault.com/q/1010000011185322/a-1020000011188451