Java併發程式設計八 執行緒池

2021-08-20 01:14:26 字數 4060 閱讀 7117

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 當乙個執行緒無事...