里面包ThreadPoolExecutor 的都不建議使用:
主要是因為
要么 無限隊列 : newSingleThreadExecutor,newFixedThreadPool
要么 無限線程 : newFixedThreadPool,newScheduledThreadPool
會OOM
可以方便的創建一些預配置的線程池,主要方法有:
newSingleThreadExecutor
:始終一個線程,所有任務排隊進行,無限隊列!:
public static ExecutorService newSingleThreadExecutor() {
return new ThreadPoolExecutor(1, 1,//始終一個線程
0L, TimeUnit.MILLISECONDS,//就一個線程,永不回收
new LinkedBlockingQueue<Runnable>());//無限排隊
}
該線程池適用于需要確保所有任務被順序執行的場合。
newFixedThreadPool
固定線程,永不回收,無限長的排隊(死鎖就是它):
用于已經知道有多大并發壓力的, 可以確定線程數的
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,//固定線程數
0L, TimeUnit.MILLISECONDS,//永不超時
new LinkedBlockingQueue<Runnable>());//無界隊列
}
如果排隊任務過多,可能會消耗非常大的內存。
newCachedThreadPool
無固定線程數.不用排隊,線程空閑60秒就回收:
適合 任務執行時間短的
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0,
Integer.MAX_VALUE,//幾乎無上限的線程數
60L, TimeUnit.SECONDS,//空閑60秒超時
new SynchronousQueue<Runnable>());//無等待隊列
}
會創建太多線程的高負荷情況下, 太多競爭CPU和內存資源,不宜使用
一般情況,任務可以不經排隊,直接交給某一個空閑線程 效率比newFixedThreadPool
高
newScheduledThreadPool
定時任務, 無限線程, 只有一個線程
newWorkStealingPool
適合大任務分解并行執行, 基于ForkJoinPool, 工作竊取的算法 把任務分解成無關的子任務