當前位置:首頁>職場>java 死鎖面試題(如何檢測并避免)
發布時間:2024-01-24閱讀(14)
作者:Yujiaaohttps://segmentfault.com/a/1190000019962661
經典但核心Java面試問題之一。
如果你沒有參與過多線程并發 Java 應用程序的編碼,你可能會失敗。
如何避免 Java 中的死鎖?
這是 Java 面試 的熱門問題之一, 也是多線程的編程中的重口味之一, 主要在招高級程序員時容易被問到, 且有很多后續問題。
盡管問題看起來非常基本, 但大多數 Java 開發人員一旦你開始深入, 就會陷入困境。
當兩個或多個線程在等待彼此釋放所需的資源(鎖定)并陷入無限等待即是死鎖。它僅在多任務或多線程的情況下發生。
雖然這可以有很多答案, 但我的版本是首先我會看看代碼, 如果我看到一個嵌套的同步塊,或從一個同步的方法調用其他同步方法, 或試圖在不同的對象上獲取鎖, 如果開發人員不是非常小心,就很容易造成死鎖。
另一種方法是在運行應用程序時實際鎖定時找到它, 嘗試采取線程轉儲,在 Linux 中,你可以通過kill -3命令執行此操作, 這將打印應用程序日志文件中所有線程的狀態, 并且你可以看到哪個線程被鎖定在哪個線程對象上。
你可以使用 fastthread.io 網站等工具分析該線程轉儲, 這些工具允許你上載線程轉儲并對其進行分析。
另一種方法是使用 jConsole 或 VisualVM, 它將顯示哪些線程被鎖定以及哪些對象被鎖定。
如果你有興趣了解故障排除工具和分析線程轉儲的過程, 我建議你看看 Uriah Levy 在多元視覺(PluraIsight)上《分析 Java 線程轉儲》課程。旨在詳細了解 Java 線程轉儲, 并熟悉其他流行的高級故障排除工具。
一旦你回答了前面的問題,他們可能會要求你編寫代碼,這將導致Java死鎖。
這是我的版本之一

如果 method1() 和 method2() 都由兩個或多個線程調用,則存在死鎖的可能性, 因為如果線程 1 在執行 method1() 時在 Sting 對象上獲取鎖, 線程 2 在執行 method2() 時在 Integer 對象上獲取鎖, 等待彼此釋放 Integer 和 String 上的鎖以繼續進行一步, 但這永遠不會發生。

此圖精確演示了我們的程序, 其中一個線程在一個對象上持有鎖, 并等待其他線程持有的其他對象鎖。
你可以看到, Thread1 需要 Thread2 持有的 Object2 上的鎖,而 Thread2 希望獲得 Thread1 持有的 Object1 上的鎖。由于沒有線程愿意放棄, 因此存在死鎖, Java 程序被卡住。
其理念是, 你應該知道使用常見并發模式的正確方法, 如果你不熟悉這些模式,那么 Jose Paumard 《應用于并發和多線程的常見 Java 模式》是學習的好起點,
現在面試官來到最后一部分, 在我看來, 最重要的部分之一; 如何修復代碼中的死鎖?或如何避免Java中的死鎖?
如果你仔細查看了上面的代碼,那么你可能已經發現死鎖的真正原因不是多個線程, 而是它們請求鎖的方式, 如果你提供有序訪問, 則問題將得到解決。
下面是我的修復版本,它通過避免循環等待,而避免死鎖, 而不需要搶占, 這是需要死鎖的四個條件之一。

現在沒有任何死鎖,因為兩種方法都按相同的順序訪問 Integer 和 String 類文本上的鎖。
因此,如果線程 A 在 Integer 對象上獲取鎖, 則線程 B 不會繼續, 直到線程 A 釋放 Integer 鎖, 即使線程 B 持有 String 鎖, 線程 A 也不會被阻止, 因為現在線程 B 不會期望線程 A 釋放 Integer 鎖以繼續。
歡迎分享轉載→http://www.avcorse.com/read-235405.html
Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號-5 TXT地圖HTML地圖XML地圖