一般我們創建Java線程池喜歡調用的api是下面這個樣子的:
newCachedThreadPool | 自增長線程 |
newFixedThreadPool | 固定線程 |
newSingleThreadExecutor | 單線程 |
NewScheduledThreadPool | 定時線程 |
newWorkStealingPool | 考慮多cpu的並行情況,把線程再fork成子線程,然後join子線程結果,合併,有些MapReduce的思想 |
前4種線程池都是
ThreadPoolExecutor的api實現的:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
5種參數的組合也就形成了上面的幾種線程池的功能:
參數名 | 作用 |
corePoolSize | 核心線程池大小,初始線程數量 |
maximumPoolSize | 最大線程池大小,當線程數量達到corePoolSize,沒有達到workQueue有界隊列的限制,又需要更多線程時,新申請的線程數量+corePoolSize 能達到最大限制數量 |
keepAliveTime | 線程池中超過corePoolSize數目的空閒線程最大存活時間;可以allowCoreThreadTimeOut(true)使得核心線程也有有效時間 |
TimeUnit | keepAliveTime時間單位 |
workQueue | 阻塞任務隊列,決定線程池的類型 |
threadFactory | 新建線程工廠,創建線程的工廠 |
RejectedExecutionHandler | 當提交任務數超過maxmumPoolSize+workQueue之和時,任務會交給RejectedExecutionHandler來處理 |
幾個參數的流程:
RejectedExecutionHandler的幾種策略:
策略 | 說明 |
ThreadPoolExecutor.AbortPolicy() | 拋出java.util.concurrent.RejectedExecutionException異常 |
ThreadPoolExecutor.CallerRunsPolicy() | 重試添加當前的任務,他會自動重複調用execute()方法 |
ThreadPoolExecutor.DiscardOldestPolicy() | 拋棄舊的任務 |
ThreadPoolExecutor.DiscardPolicy() | 拋棄當前的任務 |
newWorkStealingPool:
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
使用ForkJoinPool實現,適合長時任務,對順序無要求,其實是1.7的東西,舊瓶裝新酒啊,哈哈哈
參考文獻:
https://www.cnblogs.com/yyy-blog/p/10616531.html