更多詳細的線程池ThreadPoolExecutor資訊參考:
http://blog.csdn.net/waterbig/article/details/4794214
http://blog.csdn.net/waterbig/article/details/4794244
JAVA線程池(ThreadPoolExecutor)源碼分析
1 JDK 內建線程池
線程池類為 java.util.concurrent.ThreadPoolExecutor,常用構造方法為:
ThreadPoolExecutor(intcorePoolSize, intmaximumPoolSize,
longkeepAliveTime, TimeUnitunit,
BlockingQueue<Runnable>workQueue,
RejectedExecutionHandlerhandler)
corePoolSize:線程池維護線程的最少數量
maximumPoolSize:線程池維護線程的最大數量
keepAliveTime:線程池維護線程所允許的空閑時間
unit:線程池維護線程所允許的空閑時間的單位
workQueue:線程池所使用的緩衝隊列
handler:線程池對拒絕任務的處理策略
一個任務通過 execute(Runnable)方法被添加到線程池,任務就是一個 Runnable類型的對象,任務的執行方法就是
Runnable類型對象的run()方法。
當一個任務通過execute(Runnable)方法欲添加到線程池時:
l 如果此時線程池中的數量小於corePoolSize,即使線程池中的線程都處於空閑狀態,也要建立新的線程來處理被添加的任務。
l 如果此時線程池中的數量等於 corePoolSize,但是緩衝隊列 workQueue未滿,那麼任務被放入緩衝隊列。
l 如果此時線程池中的數量大於等於corePoolSize,緩衝隊列workQueue滿,並且線程池中的數量小於maximumPoolSize,建新的線程來處理被添加的任務。
l 如果此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,並且線程池中的數量等於maximumPoolSize,那麼通過
handler所指定的策略來處理此任務。也就是:處理任務的優先順序為:核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。
l 當線程池中的線程數量大於 corePoolSize時,如果某線程空閑時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態調整池中的線程數。
2 具體分析
以上的說明是不是很抽象,那我們就用代碼來驗證一下線程池是否按照以上的策略來嚴格執行:
Ø 首先實現Runnable的類ThreadPoolTask,為了很好的達到線程池的實戰效果,我們在run執行體中加入2秒的延時。代碼如下:
publicclassThreadPoolTaskimplementsRunnable,Serializable
{
privateObjectattachData;
ThreadPoolTask(Objecttasks)
{
this.attachData =tasks;
}
publicvoidrun() {
System.out.println("開始執行任務:"
+ attachData);
attachData =null;
try {
Thread.sleep(2000);//延時2秒,示範線程池滿
} catch (InterruptedExceptione)
{
e.printStackTrace();
}
}
publicObjectgetTask() {
returnthis.attachData;
}
}
Ø 驗證如果此時線程池中的數量等於 corePoolSize,但是緩衝隊列 workQueue未滿,那麼任務被放入緩衝隊列。
執行結果:
Ø 驗證如果此時線程池中的數量大於等於corePoolSize,緩衝隊列workQueue滿,並且線程池中的數量小於maximumPoolSize,建新的線程來處理被添加的任務
執行結果:
Ø 驗證如果此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,並且線程池中的數量等於maximumPoolSize,那麼通過
handler所指定的策略來處理此任務。也就是:處理任務的優先順序為:核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。
執行結果:
補充進行驗證handler註冊策略:
執行結果: