【发布时间】:2016-02-05 14:10:07
【问题描述】:
在 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));
}
}
Goetz 写道:
"...委托版本[上面的代码]返回一个不可修改但 车辆位置的“实时”视图。这意味着如果线程 A 调用 getLocations() 和线程 B 稍后修改一些 点,这些更改会反映在返回给线程 A 的映射中。”
在什么意义上线程 A 的 unmodifiableMap 是“活的”?我看不到线程 B 通过调用 setLocation() 所做的更改将如何反映在线程 A 的 unmodifiableMap 中。只有当线程 A 构造了一个新的 DelegatingVehicleTracker 实例时,才会出现这种情况。但是如果线程 A 持有对此类的引用,我不明白这是怎么可能的。
Goetz 继续说 getLocationsAsStatic() 可以被称为“所需舰队的不变视图”。我很迷惑。在我看来,情况恰恰相反,对 getLocationsAsStatic() 的调用确实会返回“实时”视图,而对 getLocations() 的调用,如果类没有重新构建,将返回静态的、不变的视图车队。
在这个例子中我遗漏了什么?
感谢任何想法或观点!
【问题讨论】:
标签: java multithreading concurrency delegation