[英]Deadlock between Cooperating objects
While going through the Java Concurrency in Practice
I came across the below code Deadlock , which demonstrated how a deadlock
can occur between cooperating objects
. Java Concurrency in Practice
我遇到了下面的死锁代码,它演示了如何在cooperating objects
之间发生deadlock
。 If one thread calls getImage()
and at the same time another calls setLocation()
it can lead to deadlock due to lock ordering
.如果一个线程调用getImage()
并且同时另一个线程调用setLocation()
它可能会由于lock ordering
而导致死锁。 To solve this we use Open calls
No Deadlock below .为了解决这个问题,我们在下面使用Open calls
No Deadlock 。 My doubt is inside setLocation()
in No Deadlock why are we doing synchronized(this)
again inside the already synchronized
method ?我的疑问是在No Deadlock 中的setLocation()
内部,为什么我们在已经synchronized
方法中再次执行synchronized(this)
? Isn't the synchronized
method already synchronized
on this
?是不是synchronized
已方法synchronized
在this
? How are we preventing the deadlock using the 2nd example?我们如何使用第二个示例防止死锁?
DeadLock僵局
class Taxi {
@GuardedBy("this")
private Point location, destination;
private final Dispatcher dispatcher;
public Taxi(Dispatcher dispatcher) {
this.dispatcher = dispatcher;
}
public synchronized Point getLocation() {
return location;
}
public synchronized void setLocation(Point location) {
this.location = location;
if (location.equals(destination))
dispatcher.notifyAvailable(this);
}
}
class Dispatcher {
@GuardedBy("this")
private final Set<Taxi> taxis;
@GuardedBy("this")
private final Set<Taxi> availableTaxis;
public Dispatcher() {
taxis = new HashSet<Taxi>();
availableTaxis = new HashSet<Taxi>();
}
public synchronized void notifyAvailable(Taxi taxi) {
availableTaxis.add(taxi);
}
public synchronized Image getImage() {
Image image = new Image();
for (Taxi t : taxis)
image.drawMarker(t.getLocation());
return image;
}
}
No Deadlock没有死锁
class Taxi {
@GuardedBy("this")
private Point location, destination;
private final Dispatcher dispatcher;
public synchronized Point getLocation() {
return location;
}
public synchronized void setLocation(Point location) {
boolean reachedDestination;
synchronized (this) {
this.location = location;
reachedDestination = location.equals(destination);
}
if (reachedDestination)
dispatcher.notifyAvailable(this);
}
}
class Dispatcher {
@GuardedBy("this")
private final Set<Taxi> taxis;
@GuardedBy("this")
private final Set<Taxi> availableTaxis;
public synchronized void notifyAvailable(Taxi taxi) {
availableTaxis.add(taxi);
}
public Image getImage() {
Set<Taxi> copy;
synchronized (this) {
copy = new HashSet<Taxi>(taxis);
}
Image image = new Image();
for (Taxi t : copy)
image.drawMarker(t.getLocation());
return image;
}
}
There is no deadlock in second because getImage not synchronized, so when calling getLocation no lock is held.第二次没有死锁,因为 getImage 没有同步,所以在调用 getLocation 时没有锁定。 You're right about the synchronized(this) inside setLocation, it serves no purpose.您对 setLocation 中的 synchronized(this) 是正确的,它没有任何用处。
The Taxi.setLocation
method in the "No Deadlock" code listing shouldn't be synchronized
. “无死锁”代码清单中的Taxi.setLocation
方法不应synchronized
。
The online errata page reads:在线勘误页面如下:
p.214 In Listing 10.6,
Taxi.setLocation
should not be a synchronized method. p.214 在代码清单 10.6 中,Taxi.setLocation
不应该是一个同步方法。 (The synchronized block in its body is correct, however.) (Fixed in 6th printing.) (然而,其主体中的同步块是正确的。)(在第 6 次印刷中修复。)
In the deadlock-prone code, when a thread calls Taxi.setLocation
, it first acquires the Taxi
lock.在容易死锁的代码中,当一个线程调用Taxi.setLocation
,它首先获取Taxi
锁。 And while holding the Taxi
lock , it proceeds to get the Dispatcher
lock.在持有Taxi
锁的同时,它继续获取Dispatcher
锁。
Taxi.setLocation
┌----lock Taxi
| ┌-lock Dispatcher
│ |
| └-unlock Dispatcher
└----unlock Taxi
This pattern is similar to the LeftRightDeadlock
example with nested lock acquisition.此模式类似于具有嵌套锁获取的LeftRightDeadlock
示例。
// Warning: deadlock-prone!
public void leftRight() {
synchronized (left) {
synchronized (right) {
doSomething()
}
}
}
In the revised version, note the Taxi
lock is released before acquiring the Dispatcher
lock .在修改后的版本中,注意在获取Dispatcher
锁之前释放了Taxi
锁。
Taxi.setLocation
┌----lock Taxi
└----unlock Taxi
┌----lock Dispatcher
└----unlock Dispatcher
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.