ThreadPoolExecutor原始碼分析(一)

2022-08-26 03:42:10 字數 2616 閱讀 5194

一、前言

閒來無事,博主有重新翻看了一下jdk1.8版的threadpoolexecutor原始碼,看後寫此筆記,畫個圈圈,做個記錄,這段原始碼,我看過,到處一遊,嘻嘻~~

二、threadpoolexecutor資料結構

在threadpoolexecutor的內部,主要由blockingqueue和abstractqueuedsynchronizer對其提供支援。在鎖框架中,abstractqueuedsynchronizer抽象類可以毫不誇張的說,佔據著核心地位,它提供了乙個基於fifo佇列,可以用於構建鎖或者其他相關同步裝置的基礎框架。

三、threadpoolexecutor原始碼分析

類的結構圖:

通過檢視threadpoolexecutor原始碼的建構函式,corepoolsize(核心執行緒數),maximumpoolsize(最大執行緒數),keepalivetime(當執行緒池中線程數目》核心執行緒數,空閒的執行緒等待任務,即runnable的時間,超過該時間,該空閒執行緒將被終止),workqueue(阻塞佇列,當執行緒池執行緒數》核心執行緒數時,新來的runnable任務將放到阻塞佇列中,待 worker獲取執行),threadfactory(執行緒工廠類,建立新的thread),rejectedexecutionhandler執行緒拒絕策略,預設是abortpolicy(丟擲rejectedexecutionexception異常)

前提:執行緒池的五種狀態:

running(執行緒池正常執行),shoudown(不接收提交的新runnable任務,會接著處理阻塞佇列裡面的任務),stop(不接收提交的新runnable任務,不處理阻塞佇列裡面的任務,中斷正在處理的任務)

tidying(所有的執行緒都被終止,執行自定義的鉤子方法terminated()

),terminated(執行緒池終止,終極狀態)

接下來,來看執行緒池提交方法execute(注:submit方法內部也是會呼叫execute)

public void execute(runnable command) 

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

else if (!addworker(command, false))

reject(command);

}

1:若當前執行緒池執行緒數目 < 核心執行緒數目 ,直接把runable任務加入新建的worker中,並啟動任務。

2:若執行緒池正常(ctl == running),直接建立乙個新的woker,即開啟乙個新的執行緒執行runnable任務。

3: 若執行緒池執行緒數目》核心執行緒數目,並且阻塞佇列未滿,新增到阻塞佇列中,並進行二次判斷當前執行緒池是否還是正常執行的(ctl==runnable)

becasuse:  若在此時呼叫了shutdown () or shoutdownnow()方法的話,說明執行緒池已經發出終止請求,不應該在把新的任務新增到阻塞佇列中,並且執行拒絕策略。

4:   執行緒池允許的最大執行緒數目》若執行緒池執行緒數目》核心執行緒數目 & 阻塞佇列已滿, 新建woker執行緒執行runnable任務。

5: 若執行緒池執行緒數目》=執行緒池允許的最大執行緒數目,對於新提交的任務執行拒絕策略。

在這一連串的邏輯判斷中,需要注意一下addworker這個方法,先上原始碼:

private boolean addworker(runnable firsttask, boolean core) 

}boolean workerstarted = false;

boolean workeradded = false;

worker w = null;

try

} finally

if (workeradded)

}} finally

return workerstarted;

}

該方法先判斷執行緒池狀態是否發生改變(是否還是running狀態),若不是直接返回false,判斷執行緒池當前執行緒數目是否大於核心執行緒數目,超過返回false.

否則新建woker執行緒,並把新建執行緒加入到wokers的集合中,啟動新建的執行緒。

啟動新建執行緒會呼叫worker例項裡面的run方法,run方法中調了runworker方法,研究一下這個方法:

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

} finally

}completedabruptly = false;

} finally

}

如果傳入的任務不為空,則先執行傳入的任務,執行完成後去阻塞佇列中獲取任務執行。

若傳入的任務為空,則直接去阻塞佇列裡面獲取任務執行。

若阻塞隊列為空,則runworker 執行finally**塊。執行緒池工作執行緒數目-1,把這個woker從wokers集合移除,並且中斷改woker執行緒。

,     今天就更新到這,下次持續更新ing..................

spring原始碼分析 spring原始碼分析

1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...

思科VPP原始碼分析(dpo機制原始碼分析)

vpp的dpo機制跟路由緊密結合在一起。路由表查詢 ip4 lookup 的最後結果是乙個load balance t結構。該結構可以看做是乙個hash表,裡面包含了很多dpo,指向為下一步處理動作。每個dpo都是新增路由時的乙個path的結果。dpo標準型別有 dpo drop,dpo ip nu...

redux原始碼分析(三) 原始碼部分

下面是每個部分的一些解讀 createstore apicreatestore reducer,initialstate enhancer 曾經非常好奇這個函式的第二個引數到底是initialstate還是enhancer,因為見過兩種寫法都有的,以為是版本問題。看了原始碼才發現,都可以的。如果你不...