[英]Thread-safety during construction
在“ Java Concurrency in Practice”一书中,有一个MonitorVehicleTracker
代码示例,该示例被声明为线程安全的。
@ThreadSafe
public class MonitorVehicleTracker {
@GuardedBy("this") private final Map<String, MutablePoint> locations;
public MonitorVehicleTracker(Map<String, MutablePoint> locations) {
this.locations = deepCopy(locations);
}
public synchronized Map<String, MutablePoint> getLocations() {
return deepCopy(locations);
}
public synchronized MutablePoint getLocation(String id) {
MutablePoint loc = locations.get(id);
return loc == null ? null : new MutablePoint(loc);
}
public synchronized void setLocation(String id, int x, int y) {
MutablePoint loc = locations.get(id);
if (loc == null)
throw new IllegalArgumentException("No such ID: " + id);
loc.x = x;
loc.y = y;
}
private static Map<String, MutablePoint> deepCopy(Map<String, MutablePoint> m) {
Map<String, MutablePoint> result = new HashMap<String, MutablePoint>();
for (String id : m.keySet())
result.put(id, new MutablePoint(m.get(id)));
return Collections.unmodifiableMap(result);
}
}
但是,让我们考虑一下在deepCopy()
调用期间另一个线程修改了构造函数locations
参数的情况。 这可能导致在通过keySet()
进行迭代时引发ConcurrentModificationException
。
那么这是否意味着MonitorVehicleTracker
不是完全线程安全的? 还是仅在对象构造完成之后才出现线程安全性 ,并且调用代码负责确保在MonitorVehicleTracker
实例化期间不会修改locations
?
不,该类仍然是线程安全的。
如果对象未能初始化,则并不意味着其类停止是线程安全的。 这是一个线程安全的类,未能初始化,因为它的参数被另一个破坏其thread-saftey
协定的线程错误地修改了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.