ThreadPoolExecutor填坑日誌(1)——newFixedThreadPool(1)與newSingleThreadPool()的區別

兩種工廠方法區別

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章