徹底弄懂 Java 執行緒池原理

2021-09-19 20:13:35 字數 2514 閱讀 8035

首先需要介紹一下執行緒池的兩個重要成員:

atominteger 型別。高3位儲存執行緒池狀態,低29位儲存當前執行緒數量。workercountof(c) 返回當前執行緒數量。runstateof(c) 返回當前執行緒池狀態。 執行緒池有如下狀態:

需要注意的是,worker 本身並不區分核心執行緒和非核心執行緒,核心執行緒只是概念模型上的叫法,特性是依靠對執行緒數量的判斷來實現的worker 特性如下:

submit 返回乙個 future 物件,我們可以呼叫其 get 方法獲取任務執行的結果。**很簡單,就是將 runnable 包裝成 futuretask 而已。可以看到,最終還是呼叫 execute 方法:

public future> submit(runnable task) 

複製**

futuretask 的**就不貼了,簡述一下原理:

工作執行緒數小於核心執行緒數時,直接新建核心執行緒執行任務;

大於核心執行緒數時,將任務新增進等待佇列;

佇列滿時,建立非核心執行緒執行任務;

工作執行緒數大於最大執行緒數時,拒絕任務

具體的**分析如下:

int c = ctl.get();

if (workercountof(c) < corepoolsize)

if (isrunning(c) && workqueue.offer(command))

else if (!addworker(command, false)) //新增到佇列失敗,說明佇列已滿,建立非核心執行緒執行任務

reject(command); //執行失敗說明達到最大執行緒數,拒絕任務

複製**

執行緒池使用 addworker 方法新建執行緒,第乙個引數代表要執行的任務,執行緒會將這個任務執行完畢後再從佇列取任務執行。第二引數是核心執行緒的標誌,它並不是 worker 本身的屬性,在這裡只用來判斷工作執行緒數量是否超標。

這個方法可以分成兩部分,第一部分進行一些前置判斷,並使用迴圈 cas 結構將執行緒數量加1。**如下:

private boolean addworker(runnable firsttask, boolean core) 

}... ...

}複製**

第二部分負責新建並啟動執行緒,並將 worker 新增至 hashset 中。**很簡單,沒什麼好注釋的,用了 reentrantlock 確保執行緒安全。

boolean workerstarted = false;

boolean workeradded = false;

worker w = null;

try

} finally

if (workeradded)

}} finally

return workerstarted;

}複製**

在 addworker 方法中,執行緒會被啟動。新建執行緒時,worker 將自身傳入,所以執行緒啟動後會執行 worker 的 run 方法,這個方法呼叫了 threadpoolexecutor 的 runworker 方法執行任務,runworker 中會迴圈取任務執行,執行邏輯如下:

具體**分析如下:

final void runworker(worker w)  catch (runtimeexception x)  catch (error x)  catch (throwable x)  finally 

} finally

}completedabruptly = false;

} finally

}複製**

在 runworker 方法中 gettask 方法返回 null 之後會導致執行緒執行完畢,被移除出 hashset,從而被系統銷毀。 執行緒的超時機制也是在這個方法實現的,借助於 blockingqueue 的 poll 和 take 方法。

超時機制實現原理如下:

具體**如下:

private runnable gettask() 

int wc = workercountof(c);

// 允許核心執行緒超時或者執行緒數大於核心執行緒

boolean timed = allowcorethreadtimeout || wc > corepoolsize;

// timed && timedout 這兩個引數結合起來控制超時機制

if ((wc > maximumpoolsize || (timed && timedout))

&& (wc > 1 || workqueue.isempty()))

try catch (interruptedexception retry)

}}複製**

徹底弄懂 Java 執行緒池原理

首先需要介紹一下執行緒池的兩個重要成員 atomicinteger 型別。高3位儲存執行緒池狀態,低29位儲存當前執行緒數量。workercountof c 返回當前執行緒數量。runstateof c 返回當前執行緒池狀態。執行緒池有如下狀態 需要注意的是,worker 本身並不區分核心執行緒和非...

Java執行緒池實現原理

threadpoolexecutor是jdk提供的執行緒池實現,threadpoolexector實現了execturo介面,可以自動幫助使用者建立,銷毀和保護執行緒,先來看一下最基本的使用方式 建立乙個執行緒池final executor executor new threadpoolexecut...

java 執行緒池的原理

頻繁地建立執行緒很浪費資源。執行緒池的執行緒可以復用,執行完乙個任務後可以執行另乙個任務。runstate表示當前執行緒池的狀態,它是乙個volatile變數用來保證執行緒之間的可見性 下面的幾個static final變數表示runstate可能的幾個取值。當建立執行緒池後,初始時,執行緒池處於r...