日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

如何避免Java线程中的死锁?

發(fā)布時間:2023/12/3 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何避免Java线程中的死锁? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

如何避免Java死鎖? 是Java面試中最受歡迎的問題之一,也是本季多線程的風格,主要是在高層提出,并帶有很多后續(xù)問題。 盡管問題看起來很基礎(chǔ),但是一旦您開始深入研究,大多數(shù)Java開發(fā)人員就會陷入困境。

面試問題始于“什么是僵局?”

當兩個或多個線程正在等待彼此釋放所需的資源(鎖定)并無限期陷入困境時,答案很簡單,這種情況稱為死鎖。 它只會在多任務(wù) 或多線程的情況下發(fā)生。

如何檢測Java中的死鎖?

盡管這可能會有很多答案,但我的版本是:如果我看到一個嵌套的同步塊或從另一個調(diào)用一個同步方法,或者試圖鎖定另一個對象,那么我將看一下代碼,那么很有可能發(fā)生死鎖如果開發(fā)人員不是很謹慎。

另一種方法是在運行應(yīng)用程序時實際上陷入僵局時找到它,嘗試進行線程轉(zhuǎn)儲,在Linux中,您可以通過“ kill -3”命令執(zhí)行此操作,這將在應(yīng)用程序日志文件中打印所有線程的狀態(tài)您可以看到哪個線程鎖定在哪個對象上。

您可以使用fastthread.io之類的工具來分析該線程轉(zhuǎn)儲,該工具允許您上載線程轉(zhuǎn)儲并進行分析。

另一種方法是使用jConsole / VisualVM ,它將確切顯示正在鎖定的線程以及在哪個對象上。

編寫Java程序會導(dǎo)致死鎖?

一旦回答了前面的問題,他們可能會要求您編寫代碼,這會導(dǎo)致Java死鎖?

這是我的版本之一:

/*** Java program to create a deadlock by imposing circular wait.* * @author WINDOWS 8**/ public class DeadLockDemo {/** This method request two locks, first String and then Integer*/public void method1() {synchronized (String.class) {System.out.println("Aquired lock on String.class object");synchronized (Integer.class) {System.out.println("Aquired lock on Integer.class object");}}}/** This method also requests same two lock but in exactly* Opposite order i.e. first Integer and then String. * This creates potential deadlock, if one thread holds String lock* and other holds Integer lock and they wait for each other, forever.*/public void method2() {synchronized (Integer.class) {System.out.println("Aquired lock on Integer.class object");synchronized (String.class) {System.out.println("Aquired lock on String.class object");}}} }

如果method1()和method2()都將被兩個或多個線程調(diào)用,則死鎖的可能性很大,因為如果線程1在執(zhí)行method1()時獲得Sting對象的鎖,而線程2在執(zhí)行method2時獲得Integer對象的鎖, () 都將互相等待,以釋放對Integer的鎖定 ,而String繼續(xù)進行下去,這將永遠不會發(fā)生。

此圖準確地演示了我們的程序,其中一個線程在一個對象上持有一個鎖,然后等待另一線程持有的其他對象鎖。

您會看到線程1想要鎖定對象2的鎖,該對象2由線程2持有,而線程2想要鎖定對象1的鎖,該對象1由線程1持有。由于沒有線程愿意放棄,因此存在死鎖,并且線程2 Java程序被卡住。

如何避免Java死鎖?

現(xiàn)在,面試官進入最后一部分,在我看來,這是最重要的部分。
您如何解決代碼中的死鎖? 或如何避免Java中的死鎖?

如果您仔細查看了上面的代碼,那么您可能已經(jīng)發(fā)現(xiàn)造成死鎖的真正原因不是多個線程,而是它們請求鎖定的方式,如果您提供有序訪問,那么問題將得到解決。

這是我的固定版本,它通過無效循環(huán)的循環(huán)等待來避免死鎖, 而沒有搶占 ,這是需要死鎖的四個條件之一。

public class DeadLockFixed {/*** Both method are now requesting lock in same order, first Integer and then String.* You could have also done reverse e.g. first String and then Integer,* both will solve the problem, as long as both method are requesting lock* in consistent order.*/public void method1() {synchronized (Integer.class) {System.out.println("Aquired lock on Integer.class object");synchronized (String.class) {System.out.println("Aquired lock on String.class object");}}}public void method2() {synchronized (Integer.class) {System.out.println("Aquired lock on Integer.class object");synchronized (String.class) {System.out.println("Aquired lock on String.class object");}}} }

現(xiàn)在將沒有任何死鎖,因為這兩個方法都以相同的順序訪問Integer和String類文字的鎖。 因此,如果線程A獲得了對Integer對象的鎖定,則線程B直到線程A釋放Integer鎖定后才會繼續(xù)進行,即使線程B持有字符串鎖,線程A也不會被阻塞,因為現(xiàn)在線程B不會期望線程A釋放整數(shù)鎖可繼續(xù)進行。

感謝您閱讀本文。 如果您喜歡這篇文章,請與您的朋友和同事分享。 如果您有任何疑問或反饋,請留言。

翻譯自: https://www.javacodegeeks.com/2018/08/avoid-deadlock-java-threads.html

總結(jié)

以上是生活随笔為你收集整理的如何避免Java线程中的死锁?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。