1
"Java 동시성 실습" 책에는 스레드 안전성이 있다고 명시된 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);
}
}
그러나 생성자
locations
인수가
가 deepCopy()
통화 중에 다른 thread에 의해을 수정할 때 경우를 고려 할 수 있습니다. 이로 인해
keySet()
을 반복하는 동안
ConcurrentModificationException
이 던져 질 수 있습니다.
따라서 MonitorVehicleTracker
은 스레드로부터 안전하지 않습니다. 또는 thread-safety은 객체 생성이 완료된 후에 만 나타나며 MonitorVehicleTracker
인스턴스 생성 중에 locations
이 수정되지 않도록 호출 코드가 책임 져야합니까?
오른쪽; 'locations'의'Map' 구현체는 쓰레드 - 안전하지 않지만'MonitorVehicleTracker'는 있습니다. – erickson
스레드 인터리빙으로 인해 클래스 invariant가 생성 도중 깨지는 경우에도 마찬가지입니까? –
@PavloViazovskyy 나는 그렇게 말할 것이다. –