一、前言
閒來無事,博主有重新翻看了一下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)1:若當前執行緒池執行緒數目 < 核心執行緒數目 ,直接把runable任務加入新建的worker中,並啟動任務。if (isrunning(c) && workqueue.offer(command))
else if (!addworker(command, false))
reject(command);
}
2:若執行緒池正常(ctl == running),直接建立乙個新的woker,即開啟乙個新的執行緒執行runnable任務。
3: 若執行緒池執行緒數目》核心執行緒數目,並且阻塞佇列未滿,新增到阻塞佇列中,並進行二次判斷當前執行緒池是否還是正常執行的(ctl==runnable)
becasuse: 若在此時呼叫了shutdown () or shoutdownnow()方法的話,說明執行緒池已經發出終止請求,不應該在把新的任務新增到阻塞佇列中,並且執行拒絕策略。
4: 執行緒池允許的最大執行緒數目》若執行緒池執行緒數目》核心執行緒數目 & 阻塞佇列已滿, 新建woker執行緒執行runnable任務。
5: 若執行緒池執行緒數目》=執行緒池允許的最大執行緒數目,對於新提交的任務執行拒絕策略。
在這一連串的邏輯判斷中,需要注意一下addworker這個方法,先上原始碼:
private boolean addworker(runnable firsttask, boolean core)該方法先判斷執行緒池狀態是否發生改變(是否還是running狀態),若不是直接返回false,判斷執行緒池當前執行緒數目是否大於核心執行緒數目,超過返回false.}boolean workerstarted = false;
boolean workeradded = false;
worker w = null;
try
} finally
if (workeradded)
}} finally
return workerstarted;
}
否則新建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,因為見過兩種寫法都有的,以為是版本問題。看了原始碼才發現,都可以的。如果你不...