为什么以下代码不会导致死锁?
根据我对多线程编程的有限理解,当调用getBar1()
时,sharedBuffer
将被“锁定”,因此,当方法尝试调用getBar2()
时,线程会必须等待sharedBuffer
(由自己持有!)。换句话说,getBar2()
在getBar1()
拥有(并释放sharedBuffer
)之前无法返回。但另一方面,getBar1()
也无法返回,因为它正在等待getBar2()
返回。
==>僵局。 (但实际上,它不是,这就是为什么我感到困惑)
...
Foo sharedBuffer = new Foo();
Bar1 getBar1()
{
Bar1 bar1;
synchronized (sharedBuffer)
{
bar1 = sharedBuffer.getBar1();
if (bar1 == null)
bar1 = new Bar1(sharedBuffer, getBat2());
sharedBuffer.setBar1(bar1);
}
return bar1;
}
Bar2 getBar2()
{
Bar2 bar2;
synchronized (sharedBuffer)
{
bar2 = sharedBuffer.getBar2();
if (bar2 == null)
bar2 = new Bar2();
}
return bar2;
}
...
答案 0 :(得分:3)
答案 1 :(得分:0)
当并发操作尝试以不同的顺序锁定两个或多个资源时会发生死锁,并且它们都会等待另一个资源锁定资源。
例如,线程T1和T2在资源R1和R2上同步:
您在这里所做的是基本同步,一次只允许一个对象访问sharedBuffer
。
答案 2 :(得分:0)
它没有死锁,因为你真的只有一个锁。在这两个函数中,您都锁定了sharedBuffer。当第一个线程调用getBar1()时,它会锁定sharedBuffer。当同一个线程调用getBar2()时,它会命中同步块,并且已经锁定,所以它只是进入锁定。
如果要导致死锁,请使用两个不同的值来锁定。然后,如果时间正确排列,您将只看到它。如果你想强制死锁,请确保第一个线程睡眠时间足够长,以便第二个线程获得锁定。
这里有一些会死锁的代码......(未经测试,很多都有错别字)。这应该有效,因为不同的线程具有锁定而不是想要锁定的线程。
public class Deadlock extends Thread
{
private Deadlock other;
private String name;
public static void main(String[] args)
{
Deadlock one = new Deadlock("one");
Deadlock two = new Deadlock("two");
one.setOther(two);
two.setOther(one);
one.start();
two.start();
}
public setOther(Deadlock other){ this.other = other; }
public void run() {
deadlock();
}
public synchronized deadlock() {
System.out.println("thread " + this.name + " entering this.deadlock()");
sleep(1000); // adjust as needed to guarantee deadlock
System.out.println("thread " + this.name + " calling other.deadlock()");
other.deadlock(this.name);
System.out.println(name + " - deadlock avoided!");
}
}