原文出處: http://www.cnblogs.com/xrq730/p/4979021.html 砖织, 主要講了一些源碼,沒有講公平鎖和非公平鎖
非公平鎖 lock.lock() 簡化版的步驟:(非公平鎖的核心)
基于CAS嘗試將state(鎖數(shù)量)從0設(shè)置為1
A末荐、如果設(shè)置成功侧纯,設(shè)置當(dāng)前線程為獨(dú)占鎖的線程;
B甲脏、如果設(shè)置失敗眶熬,還會(huì)再獲取一次鎖數(shù)量,
B1块请、如果鎖數(shù)量為0娜氏,再基于CAS嘗試將state(鎖數(shù)量)從0設(shè)置為1一次,如果設(shè)置成功墩新,設(shè)置當(dāng)前線程為獨(dú)占鎖的線程贸弥;
B2、如果鎖數(shù)量不為0或者上邊的嘗試又失敗了海渊,查看當(dāng)前線程是不是已經(jīng)是獨(dú)占鎖的線程了绵疲,如果是,則將當(dāng)前的鎖數(shù)量+1臣疑;如果不是盔憨,則將該線程封裝在一個(gè)Node內(nèi),并加入到等待隊(duì)列中去讯沈。等待被其前一個(gè)線程節(jié)點(diǎn)喚醒郁岩。
公平鎖的lock()
簡化版的步驟:(公平鎖的核心)
獲取一次鎖數(shù)量,
B1、如果鎖數(shù)量為0驯用,如果當(dāng)前線程是等待隊(duì)列中的頭節(jié)點(diǎn)脸秽,基于CAS嘗試將state(鎖數(shù)量)從0設(shè)置為1一次,如果設(shè)置成功蝴乔,設(shè)置當(dāng)前線程為獨(dú)占鎖的線程记餐;
B2、如果鎖數(shù)量不為0或者當(dāng)前線程不是等待隊(duì)列中的頭節(jié)點(diǎn)或者上邊的嘗試又失敗了薇正,查看當(dāng)前線程是不是已經(jīng)是獨(dú)占鎖的線程了片酝,如果是,則將當(dāng)前的鎖數(shù)量+1挖腰;如果不是雕沿,則將該線程封裝在一個(gè)Node內(nèi),并加入到等待隊(duì)列中去猴仑。等待被其前一個(gè)線程節(jié)點(diǎn)喚醒审轮。
總結(jié):公平鎖與非公平鎖對比
FairSync:lock()少了插隊(duì)部分(即少了CAS嘗試將state從0設(shè)為1,進(jìn)而獲得鎖的過程)
FairSync:tryAcquire(int acquires)多了需要判斷當(dāng)前線程是否在等待隊(duì)列首部的邏輯(實(shí)際上就是少了再次插隊(duì)的過程辽俗,但是CAS獲取還是有的)疾渣。
區(qū)別: 所謂公平鎖指的是哪個(gè)線程先運(yùn)行,那就可以先得到鎖崖飘。非公平鎖是不管線程是否是先運(yùn)行榴捡,都是隨機(jī)獲得鎖的。