多線程積累:鎖

前言

繼之前synchronized關(guān)鍵字之后烹玉,這里旨在介紹常見的鎖概念驰怎,源碼相關(guān)。
內(nèi)容會(huì)進(jìn)行不定時(shí)更新二打,希望能更完善的整理鎖相關(guān)知識(shí)點(diǎn)县忌。

公平鎖和非公平鎖

1.公平鎖

多個(gè)線程按照申請(qǐng)鎖的順序來獲取鎖,線程直接進(jìn)入隊(duì)列中排隊(duì)继效,隊(duì)列中的第一個(gè)線程才能獲得鎖症杏。

  • 優(yōu)點(diǎn):等待鎖的線程不會(huì)餓死,按照順序獲取鎖瑞信。
  • 缺點(diǎn):由于CPU喚醒線程的開銷大厉颤,所以每次都需要主動(dòng)喚醒第一個(gè)線程,相對(duì)性能較差

2.非公平鎖

多個(gè)線程加鎖時(shí)直接嘗試獲取鎖凡简,獲取不到才會(huì)到等待隊(duì)列的隊(duì)尾等待逼友。

  • 優(yōu)點(diǎn):當(dāng)線程嘗試獲取鎖時(shí)绩郎,正好可用,則直接獲取鎖翁逞,減少了喚醒線程的開銷肋杖。
  • 缺點(diǎn):處于等待隊(duì)列中的線程可能會(huì)餓死,或者等很久才會(huì)獲得鎖挖函。

ReentrantLock

ReentrantLock支持公平鎖和非公平鎖状植。
ReentrantLock里面有一個(gè)內(nèi)部類Sync,Sync繼承AQS(AbstractQueuedSynchronizer)怨喘,添加鎖和釋放鎖的大部分操作實(shí)際上都是在Sync中實(shí)現(xiàn)的津畸。它有公平鎖FairSync和非公平鎖NonfairSync兩個(gè)子類。ReentrantLock默認(rèn)使用非公平鎖public ReentrantLock() { sync = new NonfairSync(); }必怜,也可以通過構(gòu)造器來顯示的指定使用公平鎖public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }肉拓。
公平鎖與非公平鎖的lock()方法唯一的區(qū)別就在于公平鎖在獲取同步狀態(tài)時(shí)多了一個(gè)限制條件:hasQueuedPredecessors(),主要是判斷當(dāng)前線程是否位于同步隊(duì)列中的第一個(gè)梳庆。

可重入鎖和非可重入鎖

1.可重入鎖

可重入鎖指在同一個(gè)線程在外層方法獲取鎖的時(shí)候暖途,再進(jìn)入該線程的內(nèi)層方法會(huì)自動(dòng)獲取鎖。
ReentrantLock和synchronized都是可重入鎖膏执,可重入鎖的一個(gè)優(yōu)點(diǎn)是可一定程度避免死鎖驻售。

2.不可重入鎖

不可重入鎖指的是一個(gè)線程必須等其他或者同一個(gè)線程釋放鎖才能獲取鎖,所以更米,當(dāng)當(dāng)一個(gè)方法獲取到鎖之后欺栗,內(nèi)部還有其他方法或者代碼塊嘗試獲取鎖,且為不可重入鎖征峦,此時(shí)迟几,就是發(fā)生死鎖。

ReentrantLock和NonReentrantLock

ReentrantLock和NonReentrantLock都繼承父類AQS栏笆,其父類AQS中維護(hù)了一個(gè)同步狀態(tài)status來計(jì)數(shù)重入次數(shù)类腮,status初始值為0。
當(dāng)線程嘗試獲取鎖時(shí)竖伯,可重入鎖先嘗試獲取并更新status值存哲,如果status == 0表示沒有其他線程在執(zhí)行同步代碼,則把status置為1七婴,當(dāng)前線程開始執(zhí)行祟偷。如果status != 0,則判斷當(dāng)前線程是否是獲取到這個(gè)鎖的線程打厘,如果是的話執(zhí)行status+1修肠,且當(dāng)前線程可以再次獲取鎖。而非可重入鎖是直接去獲取并嘗試更新當(dāng)前status的值户盯,如果status != 0的話會(huì)導(dǎo)致其獲取鎖失敗嵌施,當(dāng)前線程阻塞饲化。
釋放鎖時(shí),可重入鎖同樣先獲取當(dāng)前status的值吗伤,在當(dāng)前線程是持有鎖的線程的前提下吃靠。如果status-1 == 0,則表示當(dāng)前線程所有重復(fù)獲取鎖的操作都已經(jīng)執(zhí)行完畢足淆,然后該線程才會(huì)真正釋放鎖巢块。而非可重入鎖則是在確定當(dāng)前線程是持有鎖的線程之后,直接將status置為0巧号,將鎖釋放族奢。

獨(dú)享鎖和共享鎖

1.獨(dú)享鎖

獨(dú)享鎖是指該鎖一次只能被一個(gè)線程所持有。
如果線程T對(duì)數(shù)據(jù)A加上獨(dú)享鎖后丹鸿,則其他線程不能再對(duì)A加任何類型的鎖越走。獲得獨(dú)享鎖的線程即能讀數(shù)據(jù)又能修改數(shù)據(jù)。
JDK中的synchronized和JUC中Lock的實(shí)現(xiàn)類就是互斥鎖靠欢。

2.共享鎖

共享鎖是指該鎖可被多個(gè)線程所持有廊敌。
如果線程T對(duì)數(shù)據(jù)A加上共享鎖后,則其他線程只能對(duì)A再加共享鎖掺涛,不能加排它鎖庭敦。獲得共享鎖的線程只能讀數(shù)據(jù),不能修改數(shù)據(jù)薪缆。

ReentrantReadWriteLock和ReentrantLock

ReentrantReadWriteLock中分為ReadLockWriteLock,鎖主體都是Sync伞广,但讀鎖和寫鎖的加鎖方式不一樣拣帽。讀鎖是共享鎖,寫鎖是獨(dú)享鎖嚼锄。讀鎖的共享鎖可保證并發(fā)讀非常高效减拭,而讀寫、寫讀区丑、寫寫的過程互斥拧粪,因?yàn)樽x鎖和寫鎖是分離的。所以ReentrantReadWriteLock的并發(fā)性相比一般的互斥鎖有了很大提升沧侥。
由源碼可知tryAcquire實(shí)現(xiàn)了寫鎖可霎,一個(gè)線程嘗試獲取鎖,當(dāng)無讀鎖或者是當(dāng)前線程已經(jīng)得到寫鎖(可重入鎖)時(shí)宴杀,才能獲取鎖癣朗。
由源碼可知tryAcquireShared實(shí)現(xiàn)了讀鎖,如果其他線程獲取寫鎖旺罢,其他線程獲取鎖失敗旷余,進(jìn)入等待狀態(tài)绢记。

ReentrantLock中實(shí)現(xiàn)了公平鎖FairSync和非公平鎖NonfairSync,可以看到都是獨(dú)享鎖。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末正卧,一起剝皮案震驚了整個(gè)濱河市蠢熄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炉旷,老刑警劉巖护赊,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砾跃,居然都是意外死亡骏啰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門抽高,熙熙樓的掌柜王于貴愁眉苦臉地迎上來判耕,“玉大人,你說我怎么就攤上這事翘骂”谙ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵碳竟,是天一觀的道長草丧。 經(jīng)常有香客問我,道長莹桅,這世上最難降的妖魔是什么昌执? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮诈泼,結(jié)果婚禮上懂拾,老公的妹妹穿的比我還像新娘。我一直安慰自己铐达,他們只是感情好岖赋,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瓮孙,像睡著了一般唐断。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上杭抠,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天脸甘,我揣著相機(jī)與錄音,去河邊找鬼祈争。 笑死斤程,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播忿墅,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼扁藕,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了疚脐?” 一聲冷哼從身側(cè)響起亿柑,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棍弄,沒想到半個(gè)月后望薄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呼畸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年痕支,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛮原。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卧须,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出儒陨,到底是詐尸還是另有隱情花嘶,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布蹦漠,位于F島的核電站椭员,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏笛园。R本人自食惡果不足惜隘击,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喘沿。 院中可真熱鬧闸度,春花似錦、人聲如沸蚜印。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窄赋。三九已至,卻和暖如春楼熄,著一層夾襖步出監(jiān)牢的瞬間忆绰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工可岂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留错敢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像稚茅,于是被迫代替她去往敵國和親纸淮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容