調(diào)用wait()會(huì)進(jìn)入到WaitSet集合中,一直等到其他獲取鎖的線程釋放鎖,從WaitSet集合中出來(lái)之后,會(huì)繼續(xù)競(jìng)爭(zhēng)對(duì)象的鎖,如果沒(méi)有競(jìng)爭(zhēng)到,那么會(huì)進(jìn)入到EntryList集合中。
阻塞態(tài)是處于內(nèi)核態(tài)的,可以通過(guò)自旋解決(Spin)避免線程阻塞。
互斥鎖的屬性:
- PTHREAD_MUTEX_TIME_NP: 這是缺省值,也就是普通鎖。當(dāng)一個(gè)線程加鎖以后,其余請(qǐng)求這把鎖的線程,其余等待這把鎖的線程將會(huì)形成一個(gè)等待隊(duì)列,并且在解鎖后按照優(yōu)先級(jí)獲取到鎖,這種策略可以確保資源分配的公平性。
- PTHREAD_MUTEX_RECURSIVE_NP: 嵌套鎖,允許同一個(gè)線程對(duì)同一把鎖成功獲取到多次,并且通過(guò)unlock解鎖,如果是不同線程請(qǐng)求,則在加鎖線程解鎖時(shí),重新進(jìn)行競(jìng)爭(zhēng)??芍厝腈i,JDK1.5引入的。
- PTHREAD_MUTEX_ERRORCHECK_NP: 檢錯(cuò)鎖,如果一個(gè)線程請(qǐng)求同一把鎖,則返回EDEADLK,否則與PTHREAD_MUTEX_TIME_NP的動(dòng)作相同,這樣就保證了當(dāng)不允許多次加鎖時(shí),不會(huì)出現(xiàn)最簡(jiǎn)單情況下的死鎖。
- PTHREAD_MUTEX_ADAPTIVE_NP:適應(yīng)鎖,動(dòng)作最簡(jiǎn)單的鎖類型,僅僅等待解鎖后重新競(jìng)爭(zhēng),不考慮優(yōu)先級(jí)。
通過(guò)底層的源碼了解Monitor對(duì)象:
JDK很多API開源的,但是很多還是不開源的,比如com.sun.*下面的API
openjdk源碼
objectMonitor.hpp
{
_header = NULL;
_count = 0;
_waiters = 0,
_recursions = 0;volatile intptr_t _recursions; // recursion count, 0 for first entry
_object = NULL;
_owner = NULL;//void * volatile _owner; // pointer to owning thread OR BasicLock
_WaitSet = NULL; //ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
_WaitSetLock = 0 ;volatile int _WaitSetLock; // protects Wait Queue - simple spinlock
_Responsible = NULL ;
_succ = NULL ;
_cxq = NULL ;ObjectWaiter * volatile _cxq ; // LL of recently-arrived threads blocked on entry. // The list is actually composed of WaitNodes, acting // as proxies for Threads.
FreeNext = NULL ;
_EntryList = NULL ;//ObjectWaiter * volatile _EntryList ; // Threads blocked on entry or reentry.
_SpinFreq = 0 ;
_SpinClock = 0 ;
OwnerIsThread = 0 ;
_previous_owner_tid = 0;
}

image.png