线程安全使用委托

huangapple go评论115阅读模式
英文:

Thread safety using Delegation

问题

通过阅读《Java并发实战》,我发现了下面的代码。

尽管 Mutablepoint 不是线程安全的,但 MonitorVehicleTracker 是线程安全的,因为保护位置映射的所有不变性都使用深拷贝。我的疑问是,由于坐标 x 和 y 是公共的,是否仍然有可能由另一个线程更改特定车辆的位置,这不会创建任何并发问题吗?那么我们如何说 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);
    }
}

@NonThreadSafe
public class MutablePoint {
    public int x, y;

    public MutablePoint() {
        x = 0;
        y = 0;
    }

    public MutablePoint(MutablePoint p) {
        this.x = p.x;
        this.y = p.y;
    }
}
英文:

While going through the Java Concurrency in Practice I came across the below code.

Even though Mutablepoint is not thread safe, MonitorVehicleTracker is Thread safe, since all the invariants that guard the locations Map use Deep copy. My doubt is, it is still possible to change the location of a particular vehicle from the Mutable point by another thread since the coordinates x and y are public, won't it create any concurrent issues? then how can we say that the MonitorVehicleTracker is Thread Safe. Can someone please explain how is this Thread Safe.

@ThreadSafe
public class MonitorVehicleTracker {
@GuardedBy(&quot;this&quot;)
private final Map&lt;String, MutablePoint&gt; locations;
public MonitorVehicleTracker(Map&lt;String, MutablePoint&gt; locations) {
this.locations = deepCopy(locations);
}
public synchronized Map&lt;String, MutablePoint&gt; 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(&quot;No such ID: &quot; + id);
loc.x = x;
loc.y = y;
}
private static Map&lt;String, MutablePoint&gt; deepCopy(Map&lt;String, MutablePoint&gt; m) {
Map&lt;String, MutablePoint&gt; result = new HashMap&lt;String, MutablePoint&gt;();
for (String id : m.keySet())
result.put(id, new MutablePoint(m.get(id)));
return Collections.unmodifiableMap(result);
}
}
@NonThreadSafe
public class MutablePoint {
public int x, y;
public MutablePoint() {
x = 0;
y = 0;
}
public MutablePoint(MutablePoint p) {
this.x = p.x;
this.y = p.y;
}
}

答案1

得分: 3

尽管MutablePoint包含公共变量,但由MotorVehicleTracker返回的所有MutablePoint实例都是地图中实例的副本。因此,如果调用者获取MutablePoint的实例并修改xy,那么这些实例与MotorVehicleTracker中存储的实例不同。因此,MotorVehicleTracker是线程安全的。MutablePoint则不是,它可能用于创建竞态条件。这些竞态条件不会涉及MotorVehicleTracker,因为该类仅存储副本并返回副本。

英文:

Even though MutablePoint contains public variables, all instances of MutablePoints returned by MotorVehicleTracker are copies of the instances in the map. Because of this, if a caller obtains an instance of MutablePoint and modifies x and y, those are different from the instances stored in the map in MotorVehicleTracker. So MotorVehicleTracker is thread safe. MutablePoint is not, and it can be used to create race conditions. Those race conditions will not involve MotorVehicleTracker because this class only stores copies, and returns copies.

huangapple
  • 本文由 发表于 2020年10月18日 14:10:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/64410261.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定