java并發(fā)編程死鎖定義及如何避免死鎖
場(chǎng)景模擬分析
場(chǎng)景一:狹路相逢
在星期天的早上十點(diǎn)半,你在公路上開(kāi)著車,這是一條窄路,只能容納一輛車。這時(shí),迎面又駛來(lái)一輛車,你們都走到一半,誰(shuí)也不想倒回去,于是各不相讓。陷入無(wú)盡的等待。
場(chǎng)景二:冷戰(zhàn)
你和她吵架了,誰(shuí)也不理誰(shuí),甚至晚飯時(shí)間都各自煮飯。你在炒京醬肉絲,她在做蔥烤鯽魚(yú)。炒到一半你發(fā)現(xiàn)小蔥被她全部拿走了,于是你默默等待她做好菜后再去拿。殊不知她也在等待你炒完菜后來(lái)拿醬油。
場(chǎng)景三:哲學(xué)家就餐
你和四個(gè)好朋友坐在圓形餐桌旁,你們只做兩件事情:吃飯,或者思考。吃飯的時(shí)候,你們就停止思考。思考的時(shí)候,也停止吃飯。每個(gè)人面前有一碗蘭州炒飯。并且每個(gè)人左右兩邊各有一根筷子。你們必須要拿到兩根筷子才能開(kāi)始吃飯。吃完后再放下筷子,讓別人可以使用。吃了一會(huì)之后,每個(gè)人都拿起了自己左手邊的筷子,導(dǎo)致每個(gè)人都只有一根筷子,并且等待別人吃完放下筷子給自己??上В瑳](méi)有人吃到飯,所以沒(méi)有人會(huì)放下筷子。(著名的哲學(xué)家就餐問(wèn)題)
場(chǎng)景四:競(jìng)爭(zhēng)資源
你有兩個(gè)線程 A 和 B ,各自在加鎖的狀態(tài)下運(yùn)行。 A 持有一部分資源,并且等待 B 線程中的資源以完成自己的工作,而此時(shí) B 線程也在等待 A 中的資源以完成自己的工作。由于他們都是鎖定狀態(tài),所以他們必須完成了自己的工作后,自己持有的資源才能釋放。于是線程無(wú)休止的等待,導(dǎo)致死鎖。
死鎖是什么?
上述四個(gè)場(chǎng)景都是程序員在工作或生活中會(huì)遇到的問(wèn)題,人生就像是一個(gè)進(jìn)程,時(shí)間是我們的主線程,期間做的每一件事都是開(kāi)啟的一個(gè)子線程。當(dāng)多件事沖突時(shí),并發(fā)問(wèn)題就產(chǎn)生了。以上場(chǎng)景都指向同一類并發(fā)問(wèn)題:死鎖。
當(dāng)兩個(gè)以上的運(yùn)算單元,雙方都在等待對(duì)方停止運(yùn)行,以獲取系統(tǒng)資源,但是沒(méi)有一方提前退出時(shí),就稱為死鎖。
產(chǎn)生死鎖的的四個(gè)條件如下:
1、互斥條件:一個(gè)資源每次只能被一個(gè)進(jìn)程使用;
2、請(qǐng)求與保持條件:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí),對(duì)已獲得的資源保持不放;
3、不剝奪條件:進(jìn)程已獲得的資源,在沒(méi)使用完之前,不能強(qiáng)行剝奪;
4、循環(huán)等待條件:多個(gè)進(jìn)程之間形成一種互相循環(huán)等待資源的關(guān)系。
并發(fā)帶來(lái)壓力,有的人或有的程序,會(huì)因?yàn)槌惺懿蛔毫Χ罎?,情緒崩潰和程序崩潰沒(méi)什么兩樣。當(dāng)然,不論是做人還是寫(xiě)程序,面對(duì)問(wèn)題時(shí),正確的做法都應(yīng)是采取策略,解除死鎖。
如何避免死鎖?
死鎖一旦發(fā)生,便無(wú)法解除。我們能做的只能盡量避免死鎖。要避免死鎖,只需破壞產(chǎn)生死鎖的四個(gè)條件之一即可。
方案一:破壞不剝奪條件
你想起書(shū)中所言:退一步海闊天空。但你也深知公平好過(guò)忍讓。正值周賽時(shí)間,你搖下車窗,對(duì)對(duì)面的兄弟喊道:咱來(lái)比賽一場(chǎng)力扣周賽,誰(shuí)輸了誰(shuí)倒出去讓另一個(gè)人過(guò)吧!于是你們打開(kāi)力扣,開(kāi)始答題。半小時(shí)后,你憑借高超的代碼水平 AC 了全部題目。對(duì)面司機(jī)對(duì)你拱手道:技不如人,甘拜下風(fēng)。于是他倒了回去,讓出了自己的一半路。最終你們都得以順利通行。
破壞不剝奪條件:讓對(duì)面的司機(jī)放棄了自己已有的資源。
方案二:破壞請(qǐng)求與保持條件
你在炒菜時(shí)發(fā)現(xiàn)沒(méi)有小蔥,于是你換位思考,想到她會(huì)不會(huì)也缺少自己用著的材料。雖然她還在和你冷戰(zhàn),但你勸解自己一個(gè)大老爺們不應(yīng)該和女孩子置氣,于是你主動(dòng)把自己用著的所有材料拿給了她。她感受到你設(shè)身處地為她著想,大為感動(dòng),你們和好如初。之后她為你們兩個(gè)人一起炒了京醬肉絲和蔥烤鯽魚(yú)。
破壞請(qǐng)求與保持條件:在自己需要的材料缺少時(shí),主動(dòng)放棄自己持有的資源,防止出現(xiàn)互相等待。
方案三:破壞循環(huán)等待條件
你和你的朋友們決定給筷子編上號(hào):1~5。規(guī)定每個(gè)人拿筷子時(shí)必須先拿到自己兩邊的筷子中號(hào)碼小的那一根,再去拿號(hào)碼大的那一根。如果小的那一根沒(méi)有拿到,不能先拿大的。當(dāng)你們開(kāi)始吃飯時(shí),由于數(shù)字 5 不可能被一個(gè)人單獨(dú)拿到。因?yàn)樗赃叺牧硪桓曜泳幪?hào)必定比 5 小,所以不會(huì)再出現(xiàn)每個(gè)人都拿著一根的無(wú)限等待情形。
破壞循環(huán)等待條件:由于筷子指定了編號(hào)和獲取規(guī)則,所以每個(gè)鎖定狀態(tài)都將按照順序執(zhí)行,于是便杜絕了環(huán)路等待條件。
方案四:破壞互斥條件
你在運(yùn)行兩個(gè)線程前,預(yù)先將線程 A 和 B 中的資源拷貝一份,讓他們不需互相等待對(duì)方的資源,于是兩個(gè)線程都得以順利運(yùn)行。
破壞互斥條件:由于每次使用時(shí)都拷貝一份,所以一個(gè)資源可以被多個(gè)進(jìn)程使用。
以上就是java并發(fā)編程死鎖定義及如何避免死鎖的詳細(xì)內(nèi)容,更多關(guān)于java死鎖及避免的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Boot配置讀取實(shí)現(xiàn)方法解析
這篇文章主要介紹了Spring Boot配置讀取實(shí)現(xiàn)方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08詳解JAVA抓取網(wǎng)頁(yè)的圖片,JAVA利用正則表達(dá)式抓取網(wǎng)站圖片
這篇文章主要介紹了詳解JAVA抓取網(wǎng)頁(yè)的圖片,JAVA利用正則表達(dá)式抓取網(wǎng)站圖片,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2016-12-12Java關(guān)于List集合去重方案詳細(xì)介紹
實(shí)際項(xiàng)目開(kāi)發(fā)中,很多業(yè)務(wù)場(chǎng)景下都會(huì)遇見(jiàn)集合去重。在說(shuō)到List集合去重之前,首先我們回顧下普通類型的list如何去重2021-09-09Java實(shí)現(xiàn)商品管理系統(tǒng)代碼實(shí)例講解
這篇文章主要介紹了Java實(shí)現(xiàn)商品管理系統(tǒng)代碼實(shí)例講解,文中代碼實(shí)例講解的很清楚,有需要的同學(xué)可以借鑒參考下2021-02-02Java中的static關(guān)鍵字修飾屬性和方法(推薦)
這篇文章主要介紹了Java中的static關(guān)鍵字修飾屬性和方法,包括哪些成員屬性可以被static修飾,靜態(tài)屬性的訪問(wèn)方法示例詳解,需要的朋友可以參考下2022-04-04在idea2023中使用SpringBoot整合Lombok全過(guò)程及詳細(xì)用法
Lombok項(xiàng)目是一個(gè)java庫(kù),它可以自動(dòng)插入到編輯器和構(gòu)建工具中,增強(qiáng)java的性能,本文詳細(xì)給大家介紹了在idea2023中使用SpringBoot整合Lombok全過(guò)程及詳細(xì)用法,需要的朋友可以參考下2023-09-09springboot prototype設(shè)置多例不起作用的解決操作
這篇文章主要介紹了springboot prototype設(shè)置多例不起作用的解決操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09