国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

總結java多線(xiàn)程之互斥與同步解決方案

發(fā)布時(shí)間:2021-07-06 11:13 來(lái)源:腳本之家 閱讀:0 作者:DaHuangXiao 欄目: 開(kāi)發(fā)技術(shù) 歡迎投稿:712375056

目錄

一、線(xiàn)程互斥與同步

互斥:指的是多個(gè)線(xiàn)程不能同時(shí)訪(fǎng)問(wèn)共享變量
同步:指的是多個(gè)線(xiàn)程按指定的順序執行操作

在同時(shí)有多個(gè)線(xiàn)程運行過(guò)程中,如何達到互斥和同步呢?

  • 加鎖即可

在此使用黑馬筆記中room例子來(lái)說(shuō)明鎖。(ps: 以前就了解鎖,但總會(huì )記亂,發(fā)現使用形象化記憶后就很清楚)

解決互斥

  • 鎖就相當于上圖的房子,里面放著(zhù)會(huì )被并發(fā)訪(fǎng)問(wèn)的共享變量
  • 此時(shí)綠色區域(owner)無(wú)線(xiàn)程,此時(shí)多個(gè)線(xiàn)程想并發(fā)訪(fǎng)問(wèn)房子里的共享變量,那么只允許其中一個(gè)線(xiàn)程進(jìn)入房子訪(fǎng)問(wèn),并把房門(mén)鎖上。
  • 剩下的沒(méi)有拿到鎖的線(xiàn)程只能在entrylist中排隊
  • owner中的線(xiàn)程訪(fǎng)問(wèn)結束后會(huì )離開(kāi)房子,并告訴entrylist的線(xiàn)程可以進(jìn)房子了
  • entrylist的線(xiàn)程開(kāi)始新一輪的掙鎖,如此反復
  • 這樣就能解決互斥的問(wèn)題

解決同步

(這涉及到為什么wait(),notify()方法需要用鎖,就是因為只有用了鎖才能完成同步,那么怎么完成的呢?)

  • 多個(gè)線(xiàn)程同時(shí)啟動(dòng),如果希望B線(xiàn)程在A(yíng)線(xiàn)程之后執行
  • 那么當B先搶到鎖,即先進(jìn)入了房子,此時(shí)A只能在entrylist中排隊
  • 為了讓A先執行,那么可以先讓B進(jìn)入藍色區域,即waitset中等待,并且把門(mén)打開(kāi),告訴entrylist中的線(xiàn)程可以進(jìn)來(lái)了
  • 那么A進(jìn)來(lái)后,執行完任務(wù),臨走時(shí)通知waitset中的B,B再回到綠色區域執行任務(wù)就能保證有序了
  • 這樣就能解決同步問(wèn)題

那么room這個(gè)數據結構其實(shí)就是synchronized的核心了,接下來(lái)總結synchronized原理的時(shí)候會(huì )一直用room的例子

二、synchronized

很多人對synchronized原理的理解也就停留在知道字節碼有個(gè)monitor關(guān)鍵字來(lái)管理鎖,再淺一點(diǎn)的只知道怎么用,再者懂得深一點(diǎn)的卻記不住。我之前就是想深入了解一下但覺(jué)得苦澀,就看不下去了,看了黑馬的筆記我覺(jué)得這玩意兒其實(shí)很簡(jiǎn)單,所以好的老師還是比較重要的。那么在此我也記錄一下怎么更好的去理解synchronized的底層原理

從字節碼我們可以知道synchronized的底層就是關(guān)聯(lián)了一個(gè)monitor,那么這玩意兒是個(gè)什么東西,怎么實(shí)現鎖的功能呢?

首先,可以把monitor的數據結構簡(jiǎn)化成上圖的room,具體點(diǎn)描述如下圖

  • synchronized(鎖對象)的時(shí)候,相當于讓鎖對象綁定了一個(gè)monitor(具體綁定方法不打算在后面總結)
  • 那么多個(gè)線(xiàn)程中方法涉及到該鎖對象時(shí),都會(huì )來(lái)訪(fǎng)問(wèn)鎖對象對應的monitor
  • 此時(shí)線(xiàn)程thread-2搶到了鎖,操作就是讓monitor中的owner字段指向thread-2線(xiàn)程,意味著(zhù)當前線(xiàn)程獲取到了基于該monitor的鎖
  • 其他沒(méi)搶到鎖的,monitor會(huì )將他們放在Entrylist中等待,這些線(xiàn)程只能在隊列中等著(zhù)
  • thread-2線(xiàn)程完成操作后就會(huì )退出,并通知entrylist的線(xiàn)程重新?lián)屾i
  • 如果在執行過(guò)程中,線(xiàn)程調用了wait()方法,monitor就會(huì )將他們放入waitset中等待別人喚醒
  • (看回room結構)owner進(jìn)入waitset后會(huì )把門(mén)打開(kāi),讓entrylist的線(xiàn)程進(jìn)來(lái)
  • 直到某時(shí)刻owner中有線(xiàn)程調用notify()方法,waitset中的線(xiàn)程才會(huì )被喚醒,喚醒后會(huì )進(jìn)入entrylist中重新?lián)屾i

以上就是synchronized的原理。有人就會(huì )問(wèn)了,你說(shuō)的這些文字我都懂啊,搞個(gè)圖擺在這也沒(méi)啥用。

接下來(lái)我將從上圖直接回答下面的常見(jiàn)的問(wèn)題

wait()和notify()為什么都得在synchronized后使用?

  • wait()就是將線(xiàn)程放入waitset中,那么waitset是在room里面的,不上鎖怎么能進(jìn)room中?同理,不進(jìn)入room,在門(mén)外怎么使用notify()怎么能叫醒waitset中的線(xiàn)程?

wait()會(huì )釋放鎖嗎?

  • 廢話(huà),不開(kāi)門(mén)的話(huà),怎么放線(xiàn)程進(jìn)來(lái),就更別提喚醒了

notifyALL()為什么不會(huì )喚醒其他鎖對象的線(xiàn)程?

  • 進(jìn)哪個(gè)room才能叫哪個(gè)waitset,進(jìn)了Aroom當然只能叫醒A的waiset了

說(shuō)說(shuō)synchronized的原理?

  •  把圖畫(huà)出來(lái)就行了

線(xiàn)程什么時(shí)候從runnable變成waiting,什么時(shí)候變成block?

  • 看圖,進(jìn)入waiset就是wait,所以調wait()就變成waiting狀態(tài)進(jìn)入entrylist就是block,所以被喚醒后以及沒(méi)搶到鎖都變block 。。。。。。。。。。。。

注意了,這里涉及monitor的原理都是synchronized最根本的原理,也稱(chēng)重量級鎖,可以看到monitor會(huì )頻繁切換線(xiàn)程狀態(tài),效率比較低。后來(lái)synchronized改進(jìn)了,在使用monitor前還有好幾種方案,分別為偏向鎖,輕量鎖,以及自旋優(yōu)化。這部分也是面試??键c(diǎn),也容易記亂,但用圖例去記就很清楚。

那么接下來(lái)就說(shuō)說(shuō)synchronized的改進(jìn)

三、輕量鎖與偏向鎖

輕量鎖與偏向鎖的核心都是先不讓線(xiàn)程沖突的時(shí)候直接去找monitor,而是先用鎖對象的對象頭字段來(lái)解決沖突

(寫(xiě)博客好累啊。。。算了我就總結一些自己覺(jué)得關(guān)鍵的地方吧)

輕量鎖

  • 對于輕量鎖而言,每個(gè)線(xiàn)程維護了一個(gè)鎖記錄,搶占鎖的過(guò)程就是用CAS將自己的信息與鎖對象的對象頭mark word部分交換
  • 這樣其他慢一步的線(xiàn)程CAS會(huì )失敗,就意識到鎖已經(jīng)被占了
  • 可重入只需要在占鎖的時(shí)候判斷鎖對象的markword記錄的是不是自己的線(xiàn)程id即可,是的話(huà)就能夠獲取鎖,也就是疊加一個(gè)鎖記錄
  • 釋放鎖就意味著(zhù)刪除鎖記錄,直到鎖記錄清空,就將鎖對象頭部被修改的字段變回原樣
  • 輕量鎖是認為不會(huì )有競爭,如果發(fā)生了線(xiàn)程競爭,鎖需要升級,不然上述方法沒(méi)有像monitor的entrylist來(lái)管理其他競爭暫時(shí)沒(méi)拿到鎖的線(xiàn)程
  • 鎖升級就是鎖膨脹,直接調monitor來(lái)管理,就將owner指向當前線(xiàn)程,然后競爭線(xiàn)程去entrylist排隊
  • 其中涉及自旋優(yōu)化,就是線(xiàn)程競爭時(shí),第二個(gè)線(xiàn)程不用立刻去entrylist中,這樣又要涉及上下文切換,可以自旋一會(huì )看鎖能否搶到

偏向鎖

  • 輕量鎖每次占鎖都要用一次CAS來(lái)更新鎖對象頭,如果本來(lái)就沒(méi)啥競爭那CAS就是無(wú)用的操作了
  • 為了解決這個(gè)問(wèn)題,線(xiàn)程搶鎖成功后直接把自己的ID刻在鎖對象頭中,需要判斷重入時(shí)只需判斷ID是否相同即可

到此這篇關(guān)于總結java多線(xiàn)程之互斥與同步解決方案的文章就介紹到這了,更多相關(guān)java多線(xiàn)程之互斥與同步內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

亚洲 丝袜 另类 校园 欧美| 99精品国产成人一区二区| 五月丁香综合缴情六月| 亚洲色精品AⅤ一区区三区| 男女18禁啪啪无遮挡| 久久精品国产精品亚洲毛片|