一直覺得這塊比較複雜,原因在於需要對資料結構和多執行緒開發比較熟悉。現在從threadpoolexecutor 出發。先看這個建構函式。
public
threadpoolexecutor
(int corepoolsize,
int maximumpoolsize,
long keepalivetime,
timeunit unit,
blockingqueue
workqueue)
來看看這個執行執行緒的方法吧。
public
void
execute
(runnable command)
//如果工作執行緒已經超過corepoolsize了,workqueue 屬於阻塞佇列。會一直阻塞加入wokrqueue佇列。
//這個workqueue是四大執行緒池不同的地方也是關鍵。當任務已滿,會阻塞,超時取消。if(
isrunning
(c)&& workqueue.
offer
(command)
)//新增非核心執行緒。如果不成功則執行拒絕策略。
elseif(
!addworker
(command,
false))
reject
(command)
;}
看下關鍵方法,addworker。看這個之前補充乙個方法。補充一點執行緒池的知識
//代表執行緒池的數量最大位佔據2^29。
private
static
final
int count_bits = integer.size -3;
//從0開始計數那麼最大整數值應該就是2^29-1.
private
static
final
int capacity =(1
<< count_bits)-1
;//這裡分析下capacity 的二進位制。00001111.......1,int第一位為符號為。~capacity為
// 11110000.....0。
//執行緒池狀態變數。running為-(2^29)。負值的二進位制為正值取反+1。(計算機中最高位為符號位,絕對值用補碼表示)2^29 值為 000100000..0 那麼running 的二進位制應該為1110 0000.....1。
private
static
final
int running =-1
<< count_bits;
//shutdown的二進位制為 00000000......0。aka 0
private
static
final
int shutdown =
0<< count_bits;
//stop的二進位制為0001000.. 0
private
static
final
int stop =
1<< count_bits;
//tidying的二進位制為0010..0
private
static
final
int tidying =
2<< count_bits;
//terminated 二進位制為 0011...0。
private
static
final
int terminated =
3<< count_bits;
// packing and unpacking ctl
//如果隨意乙個整數我要求出它的state值,那麼如何求呢?比如我取 c=000101010101000010...0。
// ~capacity 為11110000.....0,那麼c& ~capacity=0001000000000==stop。實際判斷的是除開符號位的,高三位的值。running 我110,shutdown 為000,stop為001,tidying為010,terminated 為011,
private
static
intrunstateof
(int c)
// 低29位儲存的是執行緒數量。capacity 為00001111.......1。c&capacity 正好等於低29位值。
//這段比較囉嗦可能以為位運算給人的直觀性不強,所以細緻分析了。
private
static
intworkercountof
(int c)
private
static
intctlof
(int rs,
int wc)
private
final atomicinteger ctl =
newatomicinteger
(ctlof
(running,0)
);
private
boolean
addworker
(runnable firsttask,
boolean core)
}boolean workerstarted =
false
;boolean workeradded =
false
; worker w = null;
try}
finally
//如果新增成功,則執行start,實際呼叫的是work的run,最終執行的是我們的runnable。
if(workeradded)}}
finally
return workerstarted;
}
現在在分析下shutdown() 邏輯。
public
void
shutdown()
finally
tryterminate()
;}
//更新 執行緒池的標誌shutdown or stop。
private
void
advancerunstate
(int targetstate)
}
//迴圈遍歷work,當然先記得先上鎖。
private
void
interruptidleworkers
(boolean onlyone)
catch
(securityexception ignore)
finally}if
(onlyone)
break;}
}finally
}
這裡還有個邏輯沒有完,那就是work裡面的run方法。
runworker屬於啟動執行緒的操作了,task只是乙個runnable。
final void
runworker
(worker w)
catch
(runtimeexception x)
catch
(error x)
catch
(throwable x)
finally
}finally
} completedabruptly =
false;}
finally
}
mysql 執行緒池原始碼 執行緒池原始碼解析
1.前言 我個人覺得理論性的東西可能大家都懂,但是具體的實現細節可能並不是很清楚所以才想記錄一下,加深記憶。2.關鍵原始碼解析 1 ctl private final atomicinteger ctl new atomicinteger ctlof running,0 private static...
muduo原始碼分析執行緒池
執行緒池的實現原理 在併發程式設計中,由於執行緒的反覆建立於銷毀是非常消耗時間的,在存在大量的執行緒的建立於銷毀的程式中,我們可以事先建立出一部分執行緒,然後管理這些執行緒去處理我們的任務,這樣可以節省一大部分反覆建立與銷毀的時間開銷,執行緒池的好處這裡不多說了,看一下muduo 網路庫對執行緒池的...
Tars原始碼分析 執行緒池實現
總結 前言tars底層實現了乙個執行緒池庫,主要源 位於tc thread poo.cpp,h 檔案中。執行緒池佇列涉及的核心是工作執行緒和任務佇列的設計。本文基於tars中的實現進行介紹。tc thread 執行緒池的工作執行緒類 threadworker 繼承自tc thread,它是tars實...