使用線程池的好處
1、降低資源消耗
可以重復利用已創建的線程降低線程創建和銷毀造成的消耗。
2、提高響應速度
當任務到達時,任務可以不需要等到線程創建就能立即執行。
3、提高線程的可管理性
線程是稀缺資源,如果無限制地創建,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一分配、調優和監控
threadpoolexecutor 介紹:
java 提供的線程池類;
threadpoolexecutor 作用:
兩個作用:
1,用于分離執行任務和當前線程;
2,主要設計初衷:重復利用thread 對象;
threadpoolexecutor 使用:
實例化:
1
2
3
4
5
6
7
8
|
public threadpoolexecutor( int corepoolsize, int maximumpoolsize, long keepalivetime, timeunit unit, blockingqueue<runnable> workqueue) { this (corepoolsize, maximumpoolsize, keepalivetime, unit, workqueue, executors.defaultthreadfactory(), defaulthandler); } |
這是threadpoolexecutor的構造方法之一,傳入參數最少,以下是參數說明:
corepoolsize : 設置線程池的線程核心數量;該參數作用:當向線程池中添加的任務數量小于核心數量時,線程池將優先創建新的線程,而不是重用之前已存在的線程(不管該線程可用與否);
源碼佐證,threadpoolexecutor 的 execute(runnable) 方法中有源碼如下:
maximumpoolsize : 設置線程池可創建最大線程數量;該參數作用:用于限制線程池無限制的創建線程;
源碼佐證,threadpoolexecutor 的 addworker(runnable ,boolean) 方法中有源碼如下:
keepalivetime : 設置線程池被創建線程的存活時間;
源碼佐證,threadpoolexecutor 的 gettask()方法中有源碼如下;源碼說明:創建的線程將從任務隊列中獲取一個新的任務,在keepalivetime時間之后如果還未獲取到任務,將關閉該線程;
unit :設置線程池線程存活時間的時間單位;
workqueue :設置線程池用于存放任務的隊列;
注意:threadpoolexecutor線程池是否創建新的線程不僅僅依賴于corepoolsize變量,還依賴于任務隊列的offer(e) 方法所返回的值;比如:想要創建一個cache線程池,就依賴于一個特殊的任務隊列:synchronousqueue<e>;
源碼佐證,threadpoolexecutor 的execute(runnable) 方法中有源碼如下:
示例: 創建固定線程池 和 cache線程池;
固定線程池,將corepoolsize 和 maximumpoolsize 設置相同即可,在executors.newfixedthreadpool(10)有源碼示例:
1
2
3
4
5
|
public static executorservice newfixedthreadpool( int nthreads) { return new threadpoolexecutor(nthreads, nthreads, 0l, timeunit.milliseconds, new linkedblockingqueue<runnable>()); } |
cacahe線程池,需要傳入特殊的blockingqueue對象,該對象需要在offer是返回false,并能夠在poll方法中監聽到offer進入的任務;java 提供了一個synchronousqueue類,該類就是這樣一個對象;在executors.newcachedthreadpool()方法中,有源碼示例:
1
2
3
4
5
|
public static executorservice newcachedthreadpool() { return new threadpoolexecutor( 0 , integer.max_value, 60l, timeunit.seconds, new synchronousqueue<runnable>()); } |
常用方法提示:
void execute(runnable command) : 任務提交方法;線程池將順序執行所提交的所有方法;
void shutdown() : 停止后續任務提交,但執行完當前線程池中所有任務;該方法的作用:線程池將中斷當前所有空閑的線程,但不保證一定中斷(可查看thread的interrupt方法);那么工作中的線程將繼續工作,直到完成;
源碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public void shutdown() { final reentrantlock mainlock = this .mainlock; mainlock.lock(); try { checkshutdownaccess(); advancerunstate(shutdown); interruptidleworkers(); 、 //中斷所有空閑的線程 onshutdown(); // hook for scheduledthreadpoolexecutor } finally { mainlock.unlock(); } tryterminate(); } |
list<runnable> shutdownnow() : 立即終止線程池;該方法的作用:線程池將中斷所有創建的線程,但不保存一定中斷;線程池將所有剩余的任務從任務隊列中移除,不在執行,并保存在一個list中返回給用于;
方法源碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public list<runnable> shutdownnow() { list<runnable> tasks; final reentrantlock mainlock = this .mainlock; mainlock.lock(); try { checkshutdownaccess(); advancerunstate(stop); interruptworkers(); tasks = drainqueue(); } finally { mainlock.unlock(); } tryterminate(); return tasks; } |
threadpoolexecutor 任務執行流程圖:
threadpoolexecutor 使用注意點說明:
清晰需要使用的是那種類型的線程池,在實例化threadpoolexecutor時,傳入的參數不同創建出來的線程池也將不同;尤其注意傳入blockingqueue參數,如果需要使用cache線程池,請確保blockingqueue的offer方法反回false;可以參見synchronousqueue類;
總結:
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://www.cnblogs.com/loveyoumi/p/9578251.html