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()的调用是不重新构造的类,会返回静态的,不变的视图车队.
在这个例子中我在这里错过了什么?
任何想法或观点都表示赞赏!
我认为您的困惑是由于对 的误解Collections.unmodifiableMap。Collections.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)
因此,unmodifiableMap在DelegatingVehicleTracker示例中由可变映射locations(thread-safe一个)支持。setLocation原子地改变locations,因此对于持有引用的线程来说,更改是可见的,因为unmodifiableMap知道这些线程不能改变unmodifiableMap. 读者无权访问,locations因此只能通过它来进行修改DelegatingVehicleTracker,因此得名delegation。