DelegatingVehicleTracker(第65页Goetz)如何返回"实时"视图?

Ben*_*ver 6 java concurrency multithreading delegation

在Java Concurrency in Practice的第65和66页上,Brian Goetz列出了以下代码:

@ThreadSafe
public class DelegatingVehicleTracker {
private final ConcurrentMap<String, Point> locations;
private final Map<String, Point> unmodifiableMap;

public DelegatingVehicleTracker(Map<String, Point> points) {
    locations = new ConcurrentHashMap<String, Point>(points);
    unmodifiableMap = Collections.unmodifiableMap(locations);
}

public Map<String, Point> getLocations() {
    return unmodifiableMap;
}

public Point getLocation(String id) {
    return locations.get(id);
}

public void setLocation(String id, int x, int y) {
    if (locations.replace(id, new Point(x, y)) == null)
        throw new IllegalArgumentException("invalid vehicle name: " + id);
}

// Alternate version of getLocations (Listing 4.8)
public Map<String, Point> getLocationsAsStatic() {
    return Collections.unmodifiableMap(
            new HashMap<String, Point>(locations));
}
}
Run Code Online (Sandbox Code Playgroud)

关于本课程Goetz写道:

"...委托版本[上面的代码]返回车辆位置的不可修改但"实时"视图.这意味着如果线程A调用getLocations()并且线程B稍后修改某些点的位置,那么这些更改反映在返回到线程A的映射中."

在什么意义上,线程A的不可修改的地图是"活的"?我没有看到Thread B通过调用setLocation()所做的更改将如何反映在Thread A的unmodifiableMap中.只有当Thread A构造了DelegatingVehicleTracker的新实例时,情况才会如此.但是如果线程A持有对这个类的引用,我不知道这是如何可能的.

Goetz继续说getLocationsAsStatic()可以被称为"对所需舰队的不变观点".我很迷惑.在我看来恰恰相反的情况是,对getLocationsAsStatic()的调用确实会返回"实时"视图,而对getLocations()的调用是不重新构造的类,会返回静态的,不变的视图车队.

在这个例子中我在这里错过了什么?

任何想法或观点都表示赞赏!

Sle*_*idi 4

我认为您的困惑是由于对 的误解Collections.unmodifiableMapCollections.unmodifiableMap不允许对返回的图进行直接突变,但是,对支持图进行突变是完全可以的(只要支持图允许突变)。例如:

Map<String,String> map = new HashMap<>();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap(map);

map.put("key","value");

for (String key : unmodifiableMap.keySet()) {
   System.out.println(key); // prints key
}
Run Code Online (Sandbox Code Playgroud)

因此,unmodifiableMapDelegatingVehicleTracker示例中由可变映射locationsthread-safe一个)支持。setLocation原子地改变locations,因此对于持有引用的线程来说,更改是可见的,因为unmodifiableMap知道这些线程不能改变unmodifiableMap. 读者无权访问,locations因此只能通过它来进行修改DelegatingVehicleTracker,因此得名delegation