通俗易懂地給女朋友講:執行緒池的內部原理
餐廳的約會
餐盤在燈光的照耀下格外晶瑩潔白,女朋友拿起紅酒杯輕輕地抿了一小口,對我說:“經常聽你說執行緒池,到底執行緒池到底是個什麼原理?”我楞了一下,心裡想女朋友今天是怎麼了,怎麼突然問出這麼專業的問題,但做為一個專業人士在女朋友面前也不能露怯啊,想了一下便說:“我先給你講講我前同事老王的故事吧!”
大齡程式設計師老王
老王是一個已經北漂十多年的程式設計師,歲數大了,加班加不動了,升遷也無望,於是拿著手裡的一些積蓄,回老家轉行創業。他選擇了洗浴行業,開一家洗浴中心,是的,一家正規的洗浴中心。之前在北京的時候,喜歡去的澡堂叫“清華池”,他想了想,就給自己的洗浴中心取名為“執行緒池”。
執行緒池洗浴中心
執行緒池開業以後,老王發現有顧客想做足療,於是就招聘了1個足療技師,多增加了一項業務增加了收入。隨著做足療的顧客增多,為了賺更多錢又招聘了4個足療技師。
過了一段時間,洗浴中心的生意越來越好,做足療的顧客也越來越多。但是,老王發現自己店裡的足療技師已經有5個足療技師,再招聘就太多了,支付不起再多工資了。足療技師忙不過來怎麼辦?老王是個聰明人,馬上想到辦法:讓顧客排隊,有哪個足療技師做完了,空閒出來了,就在隊伍裡再叫一個顧客繼續做。
忙碌的週末
一到週末,來洗浴中心的顧客比平時多了幾倍,想足療的顧客排隊時間太長,顧客們已經不耐煩了。老王馬上做出反應,又緊急從其他洗浴中心招聘了5個足療技師,為隊伍裡顧客做足療,大大減少排隊的顧客。
不過,有時生意太火爆了,緊急招聘的技師也用上了,顧客排隊時間也是很長,再來新的顧客,老王只能滿臉賠笑地和顧客說:“您下次再來吧,下次給您找個好技師。”,把顧客拒之門外。
過了週末以後,店裡不能養閒人啊,老王就把緊急招聘的技師都辭退了。
老王的經營之道
老王的生意越做越紅火,很快就要開分店、融資上市、走上人生巔峰。既然這麼成功,就讓我們來複盤一下他的經營之道吧。
如果你瞭解了老王的經營之道,執行緒池就不難理解了,把顧客
替換成任務
,把足療技師
替換成執行緒
,執行緒池洗浴中心
就是執行緒池
了,執行緒池的內部原理就是這樣的:
夢醒
鈴鈴鈴,鬧鈴把我吵醒,原來是一場夢啊,我哪有什麼女朋友?今天上午有一個面試,趕緊起床洗漱完畢,就出發了。在路上回想那個奇怪的夢,要不再複習一下執行緒池的內部原理吧!
先看一下ThreadPoolExecutor類的execute方法:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//獲取clt,clt記錄著執行緒池狀態和執行執行緒數。
int c = ctl.get();
//執行執行緒數小於核心執行緒數時,建立執行緒放入執行緒池中,並且執行當前任務。
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
//建立執行緒失敗,重新獲取clt。
c = ctl.get();
}
//執行緒池是執行狀態並且執行執行緒大於核心執行緒數時,把任務放入佇列中。
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//重新檢查執行緒池不是執行狀態時,
//把任務移除佇列,並通過拒絕策略對該任務進行處理。
if (! isRunning(recheck) && remove(command))
reject(command);
//當前執行執行緒數為0時,建立執行緒加入執行緒池中。
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//執行執行緒大於核心執行緒數時並且佇列已滿時,
//建立執行緒放入執行緒池中,並且執行當前任務。
else if (!addWorker(command, false))
//執行執行緒大於最大執行緒數時,失敗則拒絕該任務
reject(command);
}
在execute方法中,多次呼叫的addWorker方法,再看一下這個方法:
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
//獲取clt,clt記錄著執行緒池狀態和執行執行緒數。
int c = ctl.get();
//獲取執行緒池的執行狀態。
int rs = runStateOf(c);
//執行緒池處於關閉狀態,或者當前任務為null
//或者佇列不為空,則直接返回失敗。
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
//獲取執行緒池中的執行緒數
int wc = workerCountOf(c);
//執行緒數超過CAPACITY,則返回false;
//這裡的core是addWorker方法的第二個引數,
//如果為true則根據核心執行緒數進行比較,
//如果為false則根據最大執行緒數進行比較。
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
//嘗試增加執行緒數,如果成功,則跳出第一個for迴圈
if (compareAndIncrementWorkerCount(c))
break retry;
//如果增加執行緒數失敗,則重新獲取ctl
c = ctl.get();
//如果當前的執行狀態不等於rs,說明狀態已被改變,
//返回第一個for迴圈繼續執行
if (runStateOf(c) != rs)
continue retry;
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
//根據當前任務來建立Worker物件
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//獲得鎖以後,重新檢查執行緒池狀態
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive())
throw new IllegalThreadStateException();
//把剛剛建立的執行緒加入到執行緒池中
workers.add(w);
int s = workers.size();
//記錄執行緒池中出現過的最大執行緒數量
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
//啟動執行緒,開始執行任務
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
面試
一箇中年男子坐在我面前,對我說:“您好,我是今天的面試官。”我微笑地迴應:“您好。”面試官面無表情地問我:“執行緒池一定用過吧,能說說執行緒池的內部原理嘛?”我差點笑出聲來,自信滿滿地說……
熱文推薦:
相關文章
- Java執行緒池二:執行緒池原理Java執行緒
- 執行緒池原理執行緒
- 通俗易懂,各常用執行緒池執行的-流程圖執行緒流程圖
- 執行緒池原理初探執行緒
- ThreadPoolExecutor執行緒池內部處理淺析thread執行緒
- Java 執行緒池執行原理分析Java執行緒
- 執行緒池的實現原理執行緒
- js內部事件機制–單執行緒原理JS事件執行緒
- SpringBoot執行緒池和Java執行緒池的實現原理Spring Boot執行緒Java
- java 內部執行緒Java執行緒
- JAVA執行緒池的原理及使用Java執行緒
- Java執行緒池的使用和原理Java執行緒
- java多執行緒:執行緒池原理、阻塞佇列Java執行緒佇列
- Java面試必問之執行緒池的建立使用、執行緒池的核心引數、執行緒池的底層工作原理Java面試執行緒
- 深入學習執行緒池原理執行緒
- Java執行緒池核心原理剖析Java執行緒
- 圖解Java執行緒池原理圖解Java執行緒
- 執行緒池原理(JDK1.8)執行緒JDK
- Java執行緒池原理及分析Java執行緒
- 執行緒池原理與實踐執行緒
- 執行緒池核心原理淺析執行緒
- 淺談執行緒池(上):執行緒池的作用及CLR執行緒池執行緒
- 從原始碼的角度解析執行緒池執行原理原始碼執行緒
- Java 執行緒池的原理與實現Java執行緒
- Java面試題:執行緒池內“鬧情緒”的執行緒,怎麼辦?Java面試題執行緒
- 淺談執行緒池(中):獨立執行緒池的作用及IO執行緒池執行緒
- RxJava2.0(四)執行緒之間切換的內部原理RxJava執行緒
- Java執行緒池原始碼及原理Java執行緒原始碼
- 執行緒池ThreadPoolExecutor實現原理執行緒thread
- 手寫執行緒池,對照學習ThreadPoolExecutor執行緒池實現原理!執行緒thread
- 執行緒池續:你必須要知道的執行緒池submit()實現原理之FutureTask!執行緒MIT
- 執行緒的建立及執行緒池執行緒
- 執行緒和執行緒池執行緒
- 多執行緒【執行緒池】執行緒
- 執行緒 執行緒池 Task執行緒
- [轉]Java 執行緒池的原理與實現Java執行緒
- java--執行緒池--建立執行緒池的幾種方式與執行緒池操作詳解Java執行緒
- 執行緒與執行緒池的那些事之執行緒池篇(萬字長文)執行緒