“为什么可以?”;Java并发性在实践中如清单10.5所示;是否生成完整的快照?

“为什么可以?”;Java并发性在实践中如清单10.5所示;是否生成完整的快照?,java,multithreading,Java,Multithreading,我在实践中阅读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,

我在实践中阅读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;
    }
}
//清单10.5。合作对象之间的锁顺序死锁。不要这样做。
导入java.util.HashSet;
导入java.util.Set;
//警告:容易发生死锁!
班车{
@担保人(“本”)
专用点位置、目的地;
专用最终调度员;
公共出租车(调度员){
this.dispatcher=dispatcher;
}
公共同步点getLocation(){
返回位置;
}
公共同步无效设置位置(点位置){
这个位置=位置;
if(位置等于(目的地))
dispatcher.notifyAvailable(此);
}
}
类调度器{
@担保人(“本”)
私人终端机的士;
@担保人(“本”)
专用最终设置可用性轴;
公共调度程序(){
taxis=新HashSet();
availableTaxis=新HashSet();
}
可使用公共交通工具(出租车){
可用轴添加(滑行);
}
公共同步映像getImage(){
图像=新图像();
出租车(t:出租车)
image.drawMarker(t.getLocation());
返回图像;
}
}
然后它说:

在容易死锁的版本中,getImage会在瞬间生成车队位置的完整快照


调用
getImage
时,我们得到了调度程序的内在锁,其他线程不能修改
taxis
但是其他线程仍然可以修改
Taxi
位置
,尽管调用
getImage
的线程可能看不到更改。那么,为什么
getImage
能在那一刻生成车队位置的完整快照呢?
调用
getImage
的线程将看到位置的变化。当我阅读

此时生成快照位置的完整快照


我将其解释为,从
getImage
开始执行的那一刻起,出租车的位置就不能更改,但它们可以通过调用
Taxi
中的
setLocation
,这些更改将可见调用
getImage
的线程将看到位置更改。当我阅读

此时生成快照位置的完整快照


我将其解释为,从
getImage
开始执行的那一刻起,出租车的位置就不能改变,但它们可以通过调用
Taxi
中的
setLocation
,这些改变将是可见的

emm,当前位置与当前目的地不同?对不起,我不太明白。
setLocation
getImage
访问
location
。您已经提到了
destination
作为可以修改的变量,而
getImage
无法看到该更改
getImage
不使用
destination
,之后所有
getImage、getLocation和setLocation都会同步。问题的最后一个粗体部分询问未在任何地方使用
目的地
的位置的图像。我已编辑了问题正文,将
目的地
更改为
位置
。使用
位置
变量的所有方法都是同步的,当前位置与当前目的地不同?对不起,我不太明白。
setLocation
getImage
访问
location
。您已经提到了
destination
作为可以修改的变量,而
getImage
无法看到该更改
getImage
不使用
destination
,之后所有
getImage、getLocation和setLocation都会同步。问题的最后一个粗体部分询问未在任何地方使用
目的地
的位置的图像。我已编辑了问题正文,将
目的地
更改为
位置
。使用
位置
变量的所有方法都是同步的