1.降低資源消耗。通過重複利用已建立的執行緒降低執行緒建立和銷毀造成的消耗。
2.提高響應速度。當任務到達時,任務可以不需要的等到執行緒建立就能立即執行。
3.提高執行緒的可管理性。執行緒是稀缺資源,如果無限制的建立,不僅會消耗系統資源,還會降低系統的穩定性,使用執行緒池可以進行統一的分配,調優和監控。
我們可以通過threadpoolexecutor類來自定義執行緒池。
首先看threadpoolexecutor的構造方法。
public threadpoolexecutor(int corepoolsize,
int maximumpoolsize,
long keepalivetime,
timeunit unit,
blockingqueue workqueue,
threadfactory threadfactory,
rejectedexecutionhandler handler)
2.1 corepoolsize(核心執行緒數)
當提交乙個任務到執行緒池時,如果當前執行緒池存活的執行緒數小於corepoolsize則建立乙個新的執行緒執行任務。
如果當前執行緒數量大於等於corepoolsize 則不會繼續建立核心執行緒而是將任務存入到blockingqueue中。
如果呼叫了執行緒池的prestartallcorethreads方法,執行緒池會提前建立並啟動所有基本執行緒。
2.2 maximumpoolsize(最大執行緒數)
執行緒池允許建立的最大執行緒數。如果阻塞佇列blockingqueue滿了,並且當前的執行緒數量小於最大執行緒數時,執行緒池會繼續建立非核心執行緒。直到執行緒池中的執行緒數量等於maximumpoolsize就不會再繼續建立非核心執行緒了。
2.3 keepalivetime(執行緒空閒時存活時間)
該執行緒池中非核心執行緒閒置超時時長
乙個非核心執行緒,閒置狀態的時長超過這個引數所設定的時長,就會被銷毀掉
如果設定allowcorethreadtimeout = true,則會作用於核心執行緒
2.4 unit (存活時間單位)
keepalivetime的單位,timeunit是乙個列舉型別。
2.5 workqueue (阻塞佇列)
當提交任務時,核心執行緒數量達到corepoolsize時,會將任務存入阻塞佇列中。
阻塞佇列有以下幾種
arrayblockingqueue(有界佇列)
有界佇列,接收到任務的時候,如果沒有達到corepoolsize的值,則新建執行緒(核心執行緒)執行任務,如果達到了,則入隊等候,如果佇列已滿,則新建執行緒(非核心執行緒)執行任務,又如果匯流排程數到了maximumpoolsize,並且佇列也滿了,則進行拒絕策略。
linkedblockingqueue(無界佇列)
無界佇列,接收到任務的時候,如果當前執行緒數小於核心執行緒數,則新建執行緒(核心執行緒)處理任務;如果當前執行緒數等於核心執行緒數,則進入佇列等待。由於這個佇列沒有最大值限制,即所有超過核心執行緒數的任務都將被新增到佇列中,這也就導致了maximumpoolsize的設定失效,因為匯流排程數永遠不會超過corepoolsize。
synchronousqueue(同步佇列)
同步佇列,一種沒有緩衝的佇列,生產者生產的資料會直接被消費者獲取並消費。
delayqueue(延時佇列)
佇列內元素必須實現delayed介面,這就意味著你傳進去的任務必須先實現delayed介面。這個佇列接收到任務時,首先先入隊,只有達到了指定的延時時間,才會執行任務。
2.6 threadfactory (執行緒工廠)
建立執行緒的方式,一般很少自己實現。
2.7 handler (拒絕策略)
執行緒池執行任務流程圖
2.executors類
jdk並發包給我們提供了四種常用的建立執行緒池的方法。
newfixedthreadpool
建立乙個固定數量的核心執行緒池方法。
核心執行緒數與最大執行緒數量相等
空閒存活時間為0(無意義,因為沒有非核心執行緒)
阻塞隊列為無界佇列
當任務提交到執行緒池中,會建立nthreads個執行緒執行任務,如果超出會將所有任務存入到無界佇列內。
public
static executorservice newfixedthreadpool(int nthreads)
newcachedthreadpool
快取執行緒池
核心執行緒為0
最大執行緒為integer.max_value
存活時間為60秒
當任務提交到執行緒池中會建立執行緒,如果執行緒空閒超過60秒會銷毀空閒執行緒。
public
static executorservice newcachedthreadpool()
newsinglethreadexecutor
乙個執行緒的執行緒池
public
static executorservice newsinglethreadexecutor()
newscheduledthreadpool
定長線程池:可以延遲執行任務或者週期性的執 行某個任務
public
static scheduledexecutorservice newscheduledthreadpool(int corepoolsize)
其靜態方法返回scheduledexecutorservice 型別的物件,scheduledexecutorservice介面有四個方法進行提交任務
schedule方法:延時執行一次任務
通過建立連線池返回 executerservice介面型別的物件 ,而不得不說executerservice介面中的幾個方法
3.1 void execute(runnable command);
execute方法,只是執行傳入實現runnable介面的例項物件,並沒有返回值。
3.2 future submit(*);
submit方法有三種形式,引數不同。但是返回值都是futuretask類的例項物件。
檢視原始碼可知:
protected
runnablefuturenewtaskfor(callablecallable)
public future> submit(runnable task)
public
futuresubmit(runnable task, t result)
其實內部都new 乙個futuretask例項物件返回。
再次檢視futuretask原始碼的建構函式
public futuretask(callablecallable)
public futuretask(runnable runnable, v result)
// executors.callable(runnable, result); 原始碼最終呼叫結果
static
final
class
runnableadapter
implements
callable
public t call()
}
從原始碼中可以看出
submit(runnable task,t result) 只是將task執行並且返回傳入的result值。
而submint(callable task) 會返回我們實現call()方法的return的值。
疏漏總結(八) 執行緒池
先從構造方法裡面的引數開始說。corepoolsize 核心執行緒數 核心執行緒是一定會存在著的執行緒,也就是說,如果你設定了假如說5,那麼不管這五個執行緒有沒有任務,都會被建立出來。queuecapacity 阻塞佇列 當核心執行緒數被使用到了最大值後,新任務如果還需要建立執行緒,就會進入阻塞佇列...
java併發程式設計 執行緒池
降低資源消耗 提高響應速度 t1 執行緒建立的時間 t2 工作任務執行額時間 t3 執行緒銷毀時間 提高了執行緒的可管理性 corepoolsize 核心執行緒數 如果執行的執行緒數大於核心執行緒數,則會先進入到阻塞佇列裡 maxinumpoolsize 允許最大執行緒數 執行緒池所建立的執行緒數一...
JUC(八) 執行緒池深入講解
juc 一 locks juc 二 深入理解鎖機制 juc 三 執行緒安全類 juc 四 強大的輔助類講解 juc 五 callable juc 六 阻塞佇列 juc 七 執行緒池簡單使用 juc 八 執行緒池深入講解 3 當乙個執行緒完成任務時,它會從佇列中取下乙個任務來執行。4 當乙個執行緒無事...