在《java并发实践》一书中可以找到以下代码(10.6):
class CooperatingNoDeadlock {
@ThreadSafe
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) {
boolean reachedDestination;
synchronized (this) {
this.location = location;
reachedDestination = location.equals(destination);
}
if (reachedDestination)
dispatcher.notifyAvailable(this);
}
public synchronized Point getDestination() {
return destination;
}
public synchronized void setDestination(Point destination) {
this.destination = destination;
}
}
@ThreadSafe
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 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;
}
}
class Image {
public void drawMarker(Point p) {
}
}
}
让我们研究一下setLocation
方法:
public synchronized void setLocation(Point location) { //first synchronized
boolean reachedDestination;
synchronized (this) { // second synchronized
this.location = location;
reachedDestination = location.equals(destination);
}
if (reachedDestination)
dispatcher.notifyAvailable(this);
}
}
我不明白什么,或者同一显示器的双重同步没用?
这段代码是我在书中找到的,您可以在这里找到它:
最佳答案
这是一个错误。像这样在同一监视器上嵌套同步没有任何作用。
errata引用此 list ,“p.214:在 list 10.6 中,Taxi.setLocation
不应该是同步方法。(但是,其主体中的同步块(synchronized block)是正确的。)”
请注意,如果将同步设置在区 block 上,则调度员可以在出租车未到达目的地时收到可用出租车的通知。这似乎是错误的,但在这种特定情况下也许还有其他措施来解决这个问题。
关于java - 为什么来自 'Concurrency in practice' 的 CooperatingNoDeadlock 使用与同一监视器的双同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42555198/