In page 69 of Java Concurrency In Practice (Listing 4.11) they show the following class as thread safe example:
@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()));
}
}
Note that constructor SafePoint(int x, int y)
is public, and set non-final fields x and y without using the usual monitor this
.
Is it considered thread safe to set non-final fields in a constructor, without using the usual monitor that is otherwise used to guard these fields? If so then why? Normally we need to use the same monitor for any modification in order to assure visibility.
I noticed that the code in the site for this constructor is different, and does use the this
as monitor for setting these fields:
public SafePoint(int x, int y) {
this.set(x, y);
}
I would like to make it clear if this difference is a cosmetic one or fixes this issue?