Java死鎖問題的排查和解決方案

本篇內(nèi)容介紹了“Java死鎖問題的排查和解決方案”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)公司主營(yíng)金林網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,App定制開發(fā),金林h5重慶小程序開發(fā)搭建,金林網(wǎng)站營(yíng)銷推廣歡迎金林等地區(qū)企業(yè)咨詢

1、為什么會(huì)出現(xiàn)死鎖?

要解決Java死鎖就必須追根究底,為什么會(huì)出現(xiàn)死鎖?其實(shí)從死鎖的定義就可以看出來,一方面是因?yàn)橛袃蓚€(gè)或者兩個(gè)以上進(jìn)程,另一方面是因?yàn)橛懈?jìng)爭(zhēng)資源。

2、怎么排查代碼中出現(xiàn)了死鎖?

(1)使用 jps + jstack

在windons命令窗口,使用jps -l

使用 jstack -l 12316

(2)使用jconsole

在window打開 JConsole,JConsole是一個(gè)圖形化的監(jiān)控工具!

在windons命令窗口 ,輸出JConsole

選擇到線程的tab上

(3)使用Java Visual VM

在window打開 jvisualvm,jvisualvm是一個(gè)圖形化的監(jiān)控工具!

在windons命令窗口 ,輸出 jvisualvm

依然是切換到線程這個(gè)TAB上,很明顯的就有提示!

3、如何避免死鎖?

上面說了死鎖出現(xiàn)的原因以及通過三種方式來檢測(cè)和排查死鎖,下面更重要的東西來了,就是如何避免死鎖,如果能夠讓寫出的代碼避免死鎖出現(xiàn)也就沒有上面這些排查的過程了。最好的是從源頭控制問題,而不是后期遇到問題在去填坑。
我看了阿里巴巴中最新的開發(fā)規(guī)約,里面有對(duì)避免死鎖的說明,具體如下:

死鎖的原因就是兩個(gè)線程試圖以不同的順序來獲得相同的鎖。所以,如果所有的線程以固定的順序來獲得鎖,那么在程序中就不會(huì)出現(xiàn)鎖順序死鎖的問題。

(1)動(dòng)態(tài)的鎖順序死鎖

以一個(gè)經(jīng)典的轉(zhuǎn)賬案例來進(jìn)行說明,我們知道轉(zhuǎn)賬就是將資金從一個(gè)賬戶轉(zhuǎn)入另一個(gè)賬戶。在開始轉(zhuǎn)賬之前,首先需要獲得這兩個(gè)賬戶對(duì)象得鎖,以確保通過原子方式來更新兩個(gè)賬戶中的余額,同時(shí)又不破壞一些不變形條件,例如 賬戶的余額不能為負(fù)數(shù)。

結(jié)論:由于我們無法控制transferMoney中的參數(shù)的順序,而這些參數(shù)順序取決于外部的輸入。所以兩個(gè)線程同時(shí)調(diào)用transferMoney,一個(gè)線程從X向Y轉(zhuǎn)賬,另一個(gè)線程從Y向X轉(zhuǎn)賬,那么就會(huì)發(fā)生互相等待鎖的情況,導(dǎo)致死鎖。

解決問題方案:定義鎖的順序,并且整個(gè)應(yīng)用中都按照這個(gè)順序來獲取鎖。

方案一:使用System.identityHashCode方法,該方法返回有Object.hashCode返回的值,此時(shí)可以通過某種任意方法來決定鎖的順序。但是在極少數(shù)情況下,兩個(gè)對(duì)象可能擁有相同的散列值,在這種情況下,通過給公共變量加鎖來實(shí)現(xiàn)給鎖制定順序。所以這種方法也是用最小的代價(jià),換來了最大的安全性。

方案二:在Account中包含一個(gè)唯一的,不可變的,值。比如說賬號(hào)等。通過對(duì)這個(gè)值對(duì)對(duì)象進(jìn)行排序。

(2)在協(xié)作對(duì)象之間發(fā)生的死鎖

如果在持有鎖時(shí)調(diào)用某外部的方法,那么將出現(xiàn)活躍性問題。在這個(gè)外部方法中可能會(huì)獲取其他的鎖(這個(gè)可能產(chǎn)生死鎖),或阻塞時(shí)間過長(zhǎng),導(dǎo)致其他線程無法及時(shí)獲得當(dāng)前持有的鎖。

場(chǎng)景如下:Taxi代表出租車對(duì)象,包含當(dāng)前位置和目的地。Dispatcher代表車隊(duì)。當(dāng)一個(gè)線程收到GPS更新事件時(shí)掉用setLocation,那么它首先更新出租車的位置,然后判斷它是否到達(dá)目的地。如果已經(jīng)到達(dá),它會(huì)通知Dispatcher:它需要一個(gè)新的目的地。因?yàn)閟etLocation和notifyAvailable都是同步方法,因此掉用setLocation線程首先獲取taxi的鎖,然后在獲取Dispatcher的鎖。同樣,掉用getImage的線程首先獲取Dispatcher的鎖,再獲取每一個(gè)taxi的鎖,這兩個(gè)線程按照不同的順序來獲取鎖,因此可能導(dǎo)致死鎖。

解決方案:使用開放掉用。如果再調(diào)用某個(gè)方法時(shí)不需要持有鎖,那么這種調(diào)用就被稱為開放掉用。這種調(diào)用能有效的避免死鎖,并且易于分析線程安全。

“Java死鎖問題的排查和解決方案”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

網(wǎng)頁(yè)名稱:Java死鎖問題的排查和解決方案
當(dāng)前網(wǎng)址:http://bm7419.com/article46/jdeehg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、標(biāo)簽優(yōu)化、服務(wù)器托管、微信公眾號(hào)、做網(wǎng)站、小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名