繁体   English   中英

施工过程中的线程安全

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM