建立ThreadPoolExecutor能夠經過構造方法和Executors的靜態方法。緩存
構造方法:異步
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
corePoolSize,線程池裏最小線程數spa
maximumPoolSize,線程池裏最大線程數量,超過最大線程時候會使用RejectedExecutionHandler線程
keepAliveTime,unit,線程最大的存活時間code
workerQueue,緩存異步任務的隊列blog
threadFactory,用來構造線程池裏的worker線程隊列
線程池提交任務流程,如下代碼有簡化內存
Runnable command同步
if (workerCount < corePoolSize) {it
new Worker().run(command);
workerCount++
}
if (workerQueue.offer(command)) { //入隊
// 還沒達到maximumPoolSize 建立worker
new Worker();
workerCount++;
} else if (!addWorker(command)) { //還沒達到maximumPoolSize,建立worker並運行
handler.rejectedException(command)
}
線程池中線程不足corePoolSize的時候直接建立線程運行command,否則的話提交到隊列,其餘worker會對這個隊列作poll。
當workerQueue隊列滿了的時候,會建立新的worker,若是worker達到上限會調用handler.rejectedException方法。
Executors.newCachedThreadPool
core是0,max是無限,隊列是SynchronousQueue。無限建立線程,線程60S過時被銷燬。風險點是線程數不可控。
Executors.newFixedThreadPool
core是thread數量,max是thread數量,隊列是LinkedBlockingQueue。由於LinkedBlockingQueue是無界的,因此max不會起做用。風險點是workerQueue的長度不可控
關於ThreadPoolExecutor.DiscardPolicy和ThreadPoolExecutor.CallerRunsPolicy
一個是隊列慢了就丟棄。一個是隊列滿了就使用主線程來執行,變成同步調用的方式。主線程就是調用submit方法的線程。
個人任務是請求外部HTTP連接,且容許失敗,我但願不要影響其餘線程。
使用線程池的參數:
new ThreadPoolExecutor( 10, 100, 60, TimeUnit.SECONDS, //限制最大線程,若是是CPU密集型的任務,核心線程就用核數,最大線程就用核數的N倍 new ArrayBlockingQueue<Runnable>(1000), //固定大小,防止內存堆積過多 new NamedThreadFactory("third_retrieval"), //本身的ThreadFactory new ThreadPoolExecutor.DiscardPolicy()) //當任務對接的時候直接丟棄