我正在阅读Java并发实践,并遇到以下代码片段。
// Listing 10.5. Lock-ordering deadlock between cooperating objects. Don’t do this.
import java.util.HashSet;
import java.util.Set;
// Warning: deadlock-prone!
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;
}
}
然后它说:
在容易死锁的版本中,getImage 会生成该时刻队列位置的完整快照。
调用getImage
时,我们得到了 Dispatcher 的内在锁,其他线程不能修改taxis
,但其他线程仍然可以修改Taxi
的location
,尽管调用getImage
的线程可能看不到更改。那么,为什么getImage
可以在那一刻生成车队位置的完整快照呢?
调用getImage
的线程将看到位置更改。当我读到时
在该时刻生成快照位置的完整快照
我将其解释为从getImage
开始执行出租车的位置就无法更改,但它们可以通过Taxi
中的setLocation
调用来更改,并且这些更改将是可见