天天看點

線程池的幾種建立方式

最近線程池用的比較多,感覺挺有意思。在此記錄一下,線程池的建立有4種方式;

1 .Executors.newCachedThreadPool();

構造方法為:

線程池的幾種建立方式

可以看到,CachedThreadPool使用的是同步隊列SynchronousQueue。該隊列不會緩沖元素,有消費時,才會繼續添加任務到隊列中。是以為了保證線程池的緩沖作用,最大線程數maxPoolSize一般是INTEGER.MAX_VALUE。

官方的注釋中注明,該線程池适用于短時間的異步任務較多的場景。核心線程是0,最大線程數量是Integer.MAX_VALUE,實際上就是沒有限制,對于空閑超過60秒的線程就會回收掉。由于該線程池内部可以建立很大的線程數量,是以不适用于耗時長,且任務量大的情況。隻能是任務量大,不耗時的任務。

2 .Executors.newFixedThreadPool(3);

這種線程池,是一個固定數量的線程池,如例:我們建立了一個線程數量固定為3的線程池,實際上是核心線程為3,最大線程也為3的線程池,由于其内部維護的資料結構為:無界隊列LinkedBlockingQueue,是以當任務數量超過我們設定的線程數時,線程池會将任務投遞到無界隊列中,這個時候一定要控制投遞任務的數量。

3 .Executors.newScheduledThreadPool(10);

定時的線程池,内部維護的是一個延遲工作隊列,可以延遲執行任務,或者每隔一段時間執行一個任務。該線程池的keepAliveTime為0L,意思是:隻要線程工作完,立馬就會被回收,不會有空閑時間。

4 .Executors.newSingleThreadExecutor();

顧名思義,就是建立一個單線程的連接配接池,細心的朋友會想,這種構造方式和

new FixedThreadPool(1)有什麼差別呢?

根據官方注釋上說,兩者的差別是:後者可以重新構造核心線程的數量,但是前者不行。意思就是FixedThreadPool構造完成後可以設定核心線程的數量,但是singleThreadExecutor不行。我自己試了一下,确實是如此。SingleThreadExecutor不能重新構造核心線程的原因:根據源碼看,是因為被FinalizableDelegatedExecutorService包了一層。不能強轉成ThreadPoolExecutor,是以不能重新設定核心線程。

繼續閱讀