七撕攒、顯式鎖

一陡鹃、回顧synchronized關(guān)鍵字

synchronized關(guān)鍵字有個(gè)名字,叫做內(nèi)置鎖抖坪。
為什么有了synchronized關(guān)鍵字還有個(gè)顯式鎖呢萍鲸?
synchronized的形式很固化,因?yàn)樗仨氁玫芥i然后再釋放鎖擦俐,其他拿不到鎖的線程就處于一個(gè)阻塞狀態(tài)脊阴,我們?nèi)绻L試中斷這個(gè)線程是中斷不了的。換句話說蚯瞧,線程必須要拿到synchronized鎖為止蹬叭,拿不到鎖我就不給你中斷。
原因:
顯示鎖主要是有一個(gè)Lock接口状知,Lock中有一個(gè)方法lockInterruptibly()可以讓線程可中斷地拿鎖秽五,當(dāng)線程處于等待拿鎖的狀態(tài)的時(shí)候,我們可以在外面通知它不用去拿鎖了饥悴,你可以去做別的事情坦喘。還有個(gè)tryLock方法可以進(jìn)行嘗試獲取鎖,拿不到馬上退出等待下一次機(jī)會(huì)西设,嘗試拿鎖瓣铣。

Lock接口中的方法

排他鎖:

不管是synchronized關(guān)鍵字還是ReentrantLock,都是一種排他鎖贷揽。
排他鎖的意思是:只有拿到鎖的線程可以進(jìn)行業(yè)務(wù)邏輯的推進(jìn)棠笑,其他線程只能乖乖等著。

二禽绪、synchronized關(guān)鍵字和顯示鎖該用誰蓖救?

一般情況下使用synchronized關(guān)鍵字洪规。除非我們需要超時(shí)獲取、非阻塞獲取循捺、中斷獲取的情況下才使用Lock接口斩例,因?yàn)閟ynchronized是JDK為我們提供的內(nèi)置的語言層面的一種鎖,不管從性能還是JDK內(nèi)部?jī)?yōu)化的力度來看都要比Lock好从橘,而且Lock是一個(gè)類念赶,使用它的話必須要進(jìn)行實(shí)例化,不可避免的就需要占據(jù)Java內(nèi)存資源恰力。

三叉谜、使用Lock

1.標(biāo)準(zhǔn)用法**
lock.lock();
try{
  //do my work
}finally{
  //一定要把釋放鎖的動(dòng)作放在finally子塊里面
  lock.unlock();
}
2.實(shí)現(xiàn)Lock接口的類

實(shí)現(xiàn)Lock接口的類

1>.可重入鎖ReentrantLock
在多線程遞歸過程中,有這么一種場(chǎng)景:A線程進(jìn)入了X遞歸的代碼塊踩萎,拿到了鎖正罢,在進(jìn)一步遞歸的時(shí)候又來到了X遞歸代碼塊,但是這個(gè)時(shí)候當(dāng)前線程已經(jīng)持有了鎖驻民。synchronized在設(shè)計(jì)的時(shí)候已經(jīng)考慮到了這個(gè)問題,所以synchronized支持可重入履怯。ReentrantLock就是為了支持這一場(chǎng)景所實(shí)現(xiàn)的回还,你進(jìn)入這個(gè)方法幾次就獲取幾次,進(jìn)而需要釋放幾次叹洲。
在可重入鎖中柠硕,有一個(gè)概念,叫“鎖的公平和非公平”运提。

公平鎖:
拿鎖的時(shí)候蝗柔,線程A先獲得鎖,我一定先被滿足民泵。等待時(shí)間最長(zhǎng)的線程癣丧,一定先獲取鎖。
非公平鎖:
即使我先請(qǐng)求獲取鎖栈妆,但是我拿鎖的請(qǐng)求可能被后滿足

效率胁编?
非公平鎖的效率比公平鎖高
為什么?
拿鎖是基于阻塞的方式鳞尔,當(dāng)一個(gè)線程在拿鎖的過程中嬉橙,拿不到鎖就被操作系統(tǒng)給掛起來,當(dāng)前拿到鎖的線程處理完畢之后寥假,操作系統(tǒng)需要將等待拿鎖的線程喚醒起市框,這個(gè)過程需要大量的上下文切換,而且線程越多這個(gè)過程就越頻繁糕韧,因此對(duì)于公平鎖而言枫振,等待的線程越多喻圃,切換上下文的時(shí)間越長(zhǎng),效率越慢蒋得。而對(duì)于非公平鎖级及,是搶占式的,剛進(jìn)來的線程一直處于可運(yùn)行狀態(tài)就沒有上下文切換的時(shí)間额衙,因此效率高饮焦。
如何實(shí)現(xiàn)非公平和公平?
在ReentrantLock的構(gòu)造方法中有一個(gè)布爾值fair窍侧,如果是缺省的話县踢,就是一個(gè)非公平鎖,如果想讓它變得公平伟件,就傳入一個(gè)true即可硼啤。

ReentrantLock的構(gòu)造方法

2>.可重入鎖ReentrantReadWriteLock
讀寫鎖本質(zhì)上有兩把鎖:一把寫鎖,一把讀鎖斧账。當(dāng)線程谴返。
當(dāng)有線程持有了讀鎖的時(shí)候,其他的線程可以繼續(xù)獲取讀鎖來進(jìn)行數(shù)據(jù)的讀取操作咧织。讀鎖是可以共享的嗓袱。
當(dāng)有線程持有了寫鎖的時(shí)候,其他的線程不管是讀還是寫都不能進(jìn)行习绢。寫鎖時(shí)一種排他鎖渠抹。
當(dāng)有讀多寫少的需求的時(shí)候,使用ReentrantReadWriteLock對(duì)性能有極大的提升闪萄。
當(dāng)有讀多寫一的需求的時(shí)候梧却,使用volatile關(guān)鍵字對(duì)性能有極大的提升。
JDK1.8改進(jìn)
在JDK1.8里面對(duì)讀寫鎖又做了進(jìn)一步的改進(jìn)败去,提出了StampedLock放航,移步:https://blog.csdn.net/sunfeizhi/article/details/52135136
3>.Condition接口
我們?cè)趕ynchronized關(guān)鍵字中,如果要進(jìn)行多線程協(xié)作圆裕,會(huì)用到notify和wait方法三椿。如果要在顯式鎖方面用通知,JDK為我們提供了Condition接口葫辐。
Condition接口提供的方法:
Condition接口提供的方法

對(duì)于每個(gè)顯式鎖而言搜锰,他們內(nèi)部都有一個(gè)conditioin,通過 Lock.newCondition();去獲取耿战。
lock和Condition協(xié)調(diào)
應(yīng)該使用Condition的signal()方法而不應(yīng)該去使用signalAll()方法蛋叼,因?yàn)镃ondition鎖的時(shí)候是對(duì)于特定的顯式鎖去綁定的,通知也只會(huì)通知與綁定的鎖有關(guān)的線程。

四狈涮、顯示鎖底層構(gòu)建AQS實(shí)現(xiàn)思想--CLH隊(duì)列鎖

AQS實(shí)現(xiàn)思想

AQS不僅僅在Java語言層面用到了狐胎,在很多語言中也用到了這個(gè)思想。CLH隊(duì)列鎖是三個(gè)開發(fā)者的名字的開頭歌馍,是基于鏈表的握巢、可擴(kuò)展的、高性能的松却、公平的自旋鎖暴浦。當(dāng)一個(gè)線程A需要去獲取鎖的時(shí)候,需要構(gòu)造一個(gè)QNode節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)晓锻,QNode里面有兩個(gè)變量歌焦,一個(gè)myPred,一個(gè)locked砚哆;locked是個(gè)布爾值独撇,當(dāng)locked設(shè)置為true的時(shí)候就獲取到了鎖。myPred指向當(dāng)前線程的前驅(qū)節(jié)點(diǎn)躁锁。當(dāng)一個(gè)線程獲取鎖之后纷铣,locked變?yōu)閠rue,然后將自己添加到CLH隊(duì)列鎖的尾部,把自己的前驅(qū)屬性指向自己的前驅(qū)節(jié)點(diǎn)战转。當(dāng)下一個(gè)線程B想要獲取鎖的時(shí)候搜立,同理將線程B添加到隊(duì)列鎖的尾部,然后不停地去自旋匣吊,檢測(cè)它的前一個(gè)節(jié)點(diǎn)A有沒有釋放鎖,釋放鎖的標(biāo)志就是locked成員變量有沒有變成false,變成了false之后寸潦,B節(jié)點(diǎn)就將前驅(qū)節(jié)點(diǎn)進(jìn)行釋放色鸳,然后將自己的locked屬性設(shè)置為true獲取到鎖,進(jìn)行自己的業(yè)務(wù)操作见转。
計(jì)算機(jī)體系結(jié)構(gòu)中的SMP(對(duì)稱多處理器)都是基于CLH隊(duì)列鎖的思想實(shí)現(xiàn)的命雀。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市斩箫,隨后出現(xiàn)的幾起案子吏砂,更是在濱河造成了極大的恐慌,老刑警劉巖乘客,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狐血,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡易核,警方通過查閱死者的電腦和手機(jī)匈织,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缀匕,你說我怎么就攤上這事纳决。” “怎么了乡小?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵阔加,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我满钟,道長(zhǎng)胜榔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任零远,我火速辦了婚禮苗分,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘牵辣。我一直安慰自己摔癣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布纬向。 她就那樣靜靜地躺著择浊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逾条。 梳的紋絲不亂的頭發(fā)上琢岩,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音师脂,去河邊找鬼担孔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛吃警,可吹牛的內(nèi)容都是我干的糕篇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼酌心,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拌消!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起安券,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤墩崩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后侯勉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹦筹,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年址貌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盛龄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖余舶,靈堂內(nèi)的尸體忽然破棺而出啊鸭,到底是詐尸還是另有隱情,我是刑警寧澤匿值,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布赠制,位于F島的核電站,受9級(jí)特大地震影響挟憔,放射性物質(zhì)發(fā)生泄漏钟些。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一绊谭、第九天 我趴在偏房一處隱蔽的房頂上張望政恍。 院中可真熱鬧,春花似錦达传、人聲如沸篙耗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宗弯。三九已至,卻和暖如春搂妻,著一層夾襖步出監(jiān)牢的瞬間蒙保,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工欲主, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留邓厕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓扁瓢,卻偏偏與公主長(zhǎng)得像详恼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涤妒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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