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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

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

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

java中線程死鎖及避免

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

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

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

如何在Java中檢測(cè)死鎖?

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

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

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

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

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

一旦回答了前面的問題,他們可能會(huì)要求您編寫代碼,這會(huì)導(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()都將被兩個(gè)或多個(gè)線程調(diào)用,則死鎖的可能性很大,因?yàn)槿绻€程1在執(zhí)行method1()時(shí)獲得Sting對(duì)象的鎖,而線程2在執(zhí)行method2時(shí)獲得Integer對(duì)象的鎖, () 都將互相等待,以釋放對(duì)Integer的鎖定 ,而String繼續(xù)進(jìn)行下去,這將永遠(yuǎn)不會(huì)發(fā)生。

該圖準(zhǔn)確地演示了我們的程序,其中一個(gè)線程在一個(gè)對(duì)象上持有一個(gè)鎖,然后等待另一線程持有的其他對(duì)象鎖。

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

如何避免Java中的死鎖?

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

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

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

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)在將沒有任何死鎖,因?yàn)檫@兩個(gè)方法都以相同的順序訪問Integer和String類文字的鎖。 因此,如果線程A獲得了對(duì)Integer對(duì)象的鎖定,則直到線程A釋放Integer鎖定后,線程B才會(huì)繼續(xù)進(jìn)行,即使線程B持有字符串鎖,線程A也不會(huì)被阻塞,因?yàn)楝F(xiàn)在線程B不會(huì)期望線程A釋放整數(shù)鎖可繼續(xù)進(jìn)行。

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

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

java中線程死鎖及避免

總結(jié)

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

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