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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 死锁的检测与修复_调查死锁–第4部分:修复代码

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 死锁的检测与修复_调查死锁–第4部分:修复代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java 死鎖的檢測與修復

在這個簡短的博客系列的最后BadTransferOperation中,我一直在討論分析死鎖,我將修復BadTransferOperation代碼。 如果您已經看過本系列的其他博客 ,那么您會知道,為了達到這一點,我創建了死鎖演示代碼,展示了如何掌握線程轉儲,然后分析了線程轉儲,找出發生僵局的位置和方式。 為了節省空間,下面的討論同時引用了本系列第1部分中的Account和DeadlockDemo類,其中包含完整的代碼清單。

教科書中有關死鎖的描述通常是這樣的:“線程A將獲得對象1的鎖定,并等待對象2的鎖定,而線程B將獲得對象2的鎖定,同時等待對象1的鎖定”。 我以前的博客中顯示的堆積,并在下面突出顯示,是一個現實世界中的死鎖,其他線程,鎖和對象陷入了直接,簡單,理論上的死鎖情況。

Found one Java-level deadlock: ============================= 'Thread-21':waiting to lock monitor 7f97118bd560 (object 7f3366f58, a threads.deadlock.Account),which is held by 'Thread-20' 'Thread-20':waiting to lock monitor 7f97118bc108 (object 7f3366e98, a threads.deadlock.Account),which is held by 'Thread-4' 'Thread-4':waiting to lock monitor 7f9711834360 (object 7f3366e80, a threads.deadlock.Account),which is held by 'Thread-7' 'Thread-7':waiting to lock monitor 7f97118b9708 (object 7f3366eb0, a threads.deadlock.Account),which is held by 'Thread-11' 'Thread-11':waiting to lock monitor 7f97118bd560 (object 7f3366f58, a threads.deadlock.Account),which is held by 'Thread-20'


如果將上面的文本和圖像與以下代碼相關聯,則可以看到Thread-20已鎖定其fromAccount對象( fromAccount ),正在等待鎖定其toAccount對象(e98)

private void transfer(Account fromAccount, Account toAccount, int transferAmount) throws OverdrawnException {synchronized (fromAccount) {synchronized (toAccount) {fromAccount.withdraw(transferAmount);toAccount.deposit(transferAmount);}}}

不幸的是,由于時序問題, Thread-20無法獲得對對象e98的鎖定,因為它正在等待Thread-4釋放對該對象的鎖定。 Thread-4無法釋放鎖,因為它正在等待Thread-7 , Thread-7正在等待Thread-11而Thread-11正在等待Thread-20釋放對對象f58的鎖。 這個現實世界的僵局只是教科書描述的一個更復雜的版本。

這段代碼的問題是,從下面的代碼片段中,您可以看到我正在從Accounts數組中隨機選擇兩個Account對象作為fromAccount和toAccount并將它們鎖定。 由于fromAccount和toAccount可以引用accounts數組中的任何對象,這意味著它們以隨機順序被鎖定。

Account toAccount = accounts.get(rnd.nextInt(NUM_ACCOUNTS));Account fromAccount = accounts.get(rnd.nextInt(NUM_ACCOUNTS));

因此, 解決方法是對Account對象的鎖定方式施加順序,并且只要順序一致,任何順序都可以執行。

private void transfer(Account fromAccount, Account toAccount, int transferAmount) throws OverdrawnException {if (fromAccount.getNumber() > toAccount.getNumber()) {synchronized (fromAccount) {synchronized (toAccount) {fromAccount.withdraw(transferAmount);toAccount.deposit(transferAmount);}}} else {synchronized (toAccount) {synchronized (fromAccount) {fromAccount.withdraw(transferAmount);toAccount.deposit(transferAmount);}}}}

上面的代碼顯示了此修復程序。 在此代碼中,我使用帳號來確保首先鎖定具有最高帳號的Account對象,這樣就不會出現以上的死鎖情況。

下面的代碼是此修復程序的完整列表:

public class AvoidsDeadlockDemo {private static final int NUM_ACCOUNTS = 10;private static final int NUM_THREADS = 20;private static final int NUM_ITERATIONS = 100000;private static final int MAX_COLUMNS = 60;static final Random rnd = new Random();List<Account> accounts = new ArrayList<Account>();public static void main(String args[]) {AvoidsDeadlockDemo demo = new AvoidsDeadlockDemo();demo.setUp();demo.run();}void setUp() {for (int i = 0; i < NUM_ACCOUNTS; i++) {Account account = new Account(i, rnd.nextInt(1000));accounts.add(account);}}void run() {for (int i = 0; i < NUM_THREADS; i++) {new BadTransferOperation(i).start();}}class BadTransferOperation extends Thread {int threadNum;BadTransferOperation(int threadNum) {this.threadNum = threadNum;}@Overridepublic void run() {for (int i = 0; i < NUM_ITERATIONS; i++) {Account toAccount = accounts.get(rnd.nextInt(NUM_ACCOUNTS));Account fromAccount = accounts.get(rnd.nextInt(NUM_ACCOUNTS));int amount = rnd.nextInt(1000);if (!toAccount.equals(fromAccount)) {try {transfer(fromAccount, toAccount, amount);System.out.print(".");} catch (OverdrawnException e) {System.out.print("-");}printNewLine(i);}}System.out.println("Thread Complete: " + threadNum);}private void printNewLine(int columnNumber) {if (columnNumber % MAX_COLUMNS == 0) {System.out.print("\n");}}/*** This is the crucial point here. The idea is that to avoid deadlock you need to ensure that threads can't try* to lock the same two accounts in the same order*/private void transfer(Account fromAccount, Account toAccount, int transferAmount) throws OverdrawnException {if (fromAccount.getNumber() > toAccount.getNumber()) {synchronized (fromAccount) {synchronized (toAccount) {fromAccount.withdraw(transferAmount);toAccount.deposit(transferAmount);}}} else {synchronized (toAccount) {synchronized (fromAccount) {fromAccount.withdraw(transferAmount);toAccount.deposit(transferAmount);}}}}} }

在我的示例代碼,死鎖的發生是因為時機問題,嵌套的synchronized在我的關鍵字BadTransferOperation類。 在此代碼中, synchronized關鍵字位于相鄰的行上; 但是,最后一點,值得注意的是, synchronized關鍵字在代碼中的什么位置都沒有關系(它們不必相鄰)。 只要用同一線程鎖定兩個(或更多)不同的監視對象,就會發生排序和死鎖。

有關更多信息,請參閱本系列中的其他博客 。

該系列以及其他博客的所有源代碼都可以在Github上找到,網址為git://github.com/roghughe/captaindebug.git

參考: 調查死鎖–第4部分:來自Captain Debug博客博客的JCG合作伙伴 Roger Hughes 修復代碼 。

翻譯自: https://www.javacodegeeks.com/2012/11/investigating-deadlocks-part-4-fixing-the-code.html

java 死鎖的檢測與修復

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的java 死锁的检测与修复_调查死锁–第4部分:修复代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。