在Java Concurrency In Practice的第69页(清单4.11)中,它们显示了以下类作为线程安全的示例:
@ThreadSafe
public class SafePoint {
@GuardedBy("this") private int x, y;
private SafePoint(int[] a) {
this(a[0], a[1]);
}
public SafePoint(SafePoint p) {
this(p.get());
}
public SafePoint(int x, int y) {
this.x = x;
this.y = y;
}
public synchronized int[] get() {
return new int[]{x, y};
}
public synchronized void set(int x, int y) {
this.x = x;
this.y = y;
}
public static void main(String[] args) {
SafePoint point = new SafePoint(1, 2);
System.out.println(Arrays.toString(point.get()));
}
}
请注意,构造函数SafePoint(int x, int y)
是公共的,并且不使用常规监视器this
设置非最终字段x和y。
在不使用通常用于监视这些字段的常规监视器的情况下,在构造函数中设置非最终字段是否被认为是线程安全的?如果是这样,那为什么呢?通常,我们需要使用同一监视器进行任何修改,以确保可见性。
我注意到该站点中该构造函数的代码不同,并且确实使用this
作为监视器来设置这些字段:
public SafePoint(int x, int y) {
this.set(x, y);
}
我想弄清楚这种区别是否是修饰性的或解决了此问题?