Posted on 2011-10-12 18:05
瘋狂 閱讀(1938)
評論(0) 編輯 收藏 所屬分類:
java
最近發現幾起對ThreadPoolExecutor的誤用,其中包括自己,發現都是因為沒有仔細看注釋和內部運轉機制,想當然的揣測參數導致,先看一下新建一個ThreadPoolExecutor的構建參數:
- public ThreadPoolExecutor(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue<Runnable> workQueue,
- ThreadFactory threadFactory,
- RejectedExecutionHandler handler)
看這個參數很容易讓人以為是線程池里保持corePoolSize個線程,如果不夠用,就加線程入池直至maximumPoolSize大小,如果還不夠就往workQueue里加,如果workQueue也不夠就用RejectedExecutionHandler來做拒絕處理。
但實際情況不是這樣,具體流程如下:
1)線程池的大小>活動的線程 就放入queue,由于有空閑的線程,就不創建線程直接用空閑的線程處理
2)線程池的大小<活動的線程&& 線程池的大小>=最大限制數,沒有空閑的線程,但不能創建線程,事件入queue等待有空閑的線程,如果超時,使RejectedExecutionHandler處理
3)線程池的大小<活動的線程&& 線程池的大小<最大限制數,沒有空閑線程,可以創建線程,直接創建新線程處理新事件
內部結構如下所示:
從中可以發現ThreadPoolExecutor就是依靠BlockingQueue的阻塞機制來維持線程池,當池子里的線程無事可干的時候就通過workQueue.take()阻塞住。
其實可以通過Executes來學學幾種特殊的ThreadPoolExecutor是如何構建的。
- public static ExecutorService newFixedThreadPool(int nThreads) {
- return new ThreadPoolExecutor(nThreads, nThreads,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue<Runnable>());
- }
newFixedThreadPool就是一個固定大小的ThreadPool
- public static ExecutorService newCachedThreadPool() {
- return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
- 60L, TimeUnit.SECONDS,
- new SynchronousQueue<Runnable>());
- }
newCachedThreadPool比較適合沒有固定大小并且比較快速就能完成的小任務,沒必要維持一個Pool,這比直接new Thread來處理的好處是能在60秒內重用已創建的線程。
其他類型的ThreadPool看看構建參數再結合上面所說的特性就大致知道它的特性
轉載自:http://blog.csdn.net/cutesource/article/details/6061229