-1

第 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. }
4

2 回答 2

5

由于锁定顺序不一致,可能会发生死锁,这意味着一个线程可能已获取resourceA并正在等待,resourceB而另一个线程已获取resourceB但正在等待resourceA。例如:

  • T1 调用read(),成功获取resourceA,然后被挂起。
  • T2调用write(),成功获取resourceB并等待resourceA
  • T1 已恢复并正在等待resourceB(永远不会被释放T2)。

两者都不能T1T2不能进步,因为每个人都在等待另一个人锁定的资源。始终具有一致的锁定顺序:

public int read() {
    synchronized(resourceA) { 
        synchronized(resourceB) {

public void write() {
    synchronized(resourceA) { 
        synchronized(resourceB) {

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

于 2013-07-16T11:39:54.053 回答
0

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

要继续,读需要resourceB,但写已经有resourceB。write一拿到resourceA就可以释放resourceB,但是read有resourceA不能放弃,直到resourceB给它。

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

于 2013-07-16T11:41:03.313 回答