同步死锁

时间:2013-07-16 11:38:34

标签: java multithreading synchronization deadlock

第8行或第16行是如何发生死锁的?

 1. public class DeadlockRisk {
 2.   private static class Resource {
 3.     public int value;
 4.   }
 5.   private Resource resourceA = new Resource();
 6.   private Resource resourceB = new Resource();
 7.   public int read() {
 8.     synchronized(resourceA) { 
 9.       synchronized(resourceB) {
10.         return resourceB.value + resourceA.value;
11.       }
12.     }
13.   }
14
15.   public void write(int a, int b) {
16.     synchronized(resourceB) { 
17.       synchronized(resourceA) {
18.         resourceA.value = a;
19.         resourceB.value = b;
20.       }
21.     }
22.   }
23. }

2 个答案:

答案 0 :(得分:5)

可能发生死锁,因为锁定顺序不一致,这意味着一个线程可以获取resourceA并等待resourceB而另一个线程已获得resourceB但正在等待{{1} }}。例如:

  • T1致电resourceA,成功获取read(),然后暂停。
  • T2致电resourceA,成功获取write()并等待resourceB
  • T1已恢复正在等待resourceAresourceB永远不会释放)。

T2T1都无法进展,因为每个人都在等待另一个已锁定的资源。始终拥有一致的锁定顺序:

T2

(但是,在发布的代码中似乎没有理由拥有多个锁,因为总是获取两个锁。)

答案 1 :(得分:0)

读取将resourceA作为外部锁的一部分。写获取资源B.这发生在任一线程锁定内部锁的对象之前。

要继续,read需要resourceB,但write已经有了resourceB。写入可以在获得resourceA后立即释放资源B,但读取具有resourceA,并且在给予resourceB之前无法放弃它。

作为一般提示,在锁定多个对象时使用一致的顺序。两者中的A和B,或两者中的B和A。