英文:
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("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;
}
}
答案1
得分: 3
尽管MutablePoint
包含公共变量,但由MotorVehicleTracker
返回的所有MutablePoint
实例都是地图中实例的副本。因此,如果调用者获取MutablePoint
的实例并修改x
和y
,那么这些实例与MotorVehicleTracker
中存储的实例不同。因此,MotorVehicleTracker
是线程安全的。MutablePoint
则不是,它可能用于创建竞态条件。这些竞态条件不会涉及MotorVehicleTracker
,因为该类仅存储副本并返回副本。
英文:
Even though MutablePoint
contains public variables, all instances of MutablePoint
s 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论