java中线程死锁及避免_如何避免Java线程中的死锁?
java中線程死鎖及避免
如何避免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程序會導致死鎖?
一旦回答了前面的問題,他們可能會要求您編寫代碼,這會導致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對象的鎖定,則直到線程A釋放Integer鎖定后,線程B才會繼續(xù)進行,即使線程B持有字符串鎖,線程A也不會被阻塞,因為現(xiàn)在線程B不會期望線程A釋放整數(shù)鎖可繼續(xù)進行。
感謝您閱讀本文。 如果您喜歡這篇文章,請與您的朋友和同事分享。 如果您有任何疑問或反饋,請留言。
翻譯自: https://www.javacodegeeks.com/2018/08/avoid-deadlock-java-threads.html
java中線程死鎖及避免
總結(jié)
以上是生活随笔為你收集整理的java中线程死锁及避免_如何避免Java线程中的死锁?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计类工作室怎么盈利(开个设计工作室怎么
- 下一篇: 东软oa安卓版(oa安卓版)