[英]Use Collections.unmodifiableMap with ConcurrentHashMap / HashMap as a parameter
我從Goetz的書(Java Concurrency in Practice)中獲得了以下代碼。
該書說,將ConcurrentMap作為Collections.unmodifiableMap中的參數傳遞,將給出位置的“實時”視圖(即,調用下面的getLocations()),這意味着對setLocation的調用將反映給調用者。
但是,將HashMap作為Collections.unmodifiableMap中的參數傳遞將給出位置的原始視圖(靜態視圖)(即,調用下面的getLocationsAsStatic())
誰能解釋其背后的原因? 謝謝
@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));
}
}
@Immutable
public class Point {
public final int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
行為上的差異不是由於地圖的類型不同,而是由於它們是如何創建的。 Collections.unmodifiableMap
只是包裝給定的地圖。
您的ConcurrentMap<String, Point> locations
是您要修改的地圖,因此,在包裝它時,使用不可修改的地圖時,您仍然會看到最新的值。
但是,您的HashMap
是使用new HashMap<String, Point>(locations)
。 該構造函數的文檔說:
使用與指定Map相同的映射構造一個新的HashMap。
參數:
m-要在其地圖中放置其映射的地圖
因此,它實際上將給定映射的所有條目復制到新創建的條目中。 因此,此新地圖不再與locations
地圖相關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.