Java 施工期间的螺纹安全

Java 施工期间的螺纹安全,java,multithreading,Java,Multithreading,在《Java并发实践》一书中,有一个MonitorVehicleTracker代码示例,它被认为是线程安全的 @ThreadSafe public class MonitorVehicleTracker { @GuardedBy("this") private final Map<String, MutablePoint> locations; public MonitorVehicleTracker(Map<String, MutablePoint>

在《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);
    }
}
@ThreadSafe
公共类监视器车辆追踪器{
@Guardby(“本”)私人最终地图位置;
公共监视器车辆追踪器(地图位置){
this.locations=deepCopy(位置);
}
公共同步映射getLocations(){
返回副本(位置);
}
公共同步可变点getLocation(字符串id){
可变点位置=位置。获取(id);
返回loc==null?null:新可变点(loc);
}
公共同步的void setLocation(字符串id,int x,int y){
可变点位置=位置。获取(id);
如果(loc==null)
抛出新的IllegalArgumentException(“无此类ID:+ID”);
loc.x=x;
位置y=y;
}
私有静态映射deepCopy(映射m){
映射结果=新的HashMap();
对于(字符串id:m.keySet())
结果.put(id,新可变点(m.get(id));
返回集合。不可修改映射(结果);
}
}

但请考虑构造函数<代码>位置< /C>参数在另一个线程中在<代码> Debug()/<代码>调用期间被修改的情况。这可能导致在遍历

keySet()
时抛出
ConcurrentModificationException


那么这是否意味着
MonitorVehicleTracker
不是完全线程安全的呢?或者线程安全性只有在对象构造完成后才会出现,调用代码负责确保
位置在
MonitorVehicleTracker
实例化期间不会被修改?

否,该类仍然是线程安全的


如果对象未能初始化,那么这并不意味着它的类是线程安全的。它是一个线程安全类,初始化失败,因为它的参数被另一个线程错误地修改,破坏了它的
线程安全
契约

对,;
Map
实现的
locations
不是线程安全的,但是
MonitorVehicleTracker
是线程安全的。当类不变量在构造过程中由于线程交错而被破坏时,这同样适用吗?@pavloviazovsky我会这么说