I am reading the concurrency in practice.
There is following example(4.3.5):
@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;
}
}
Author acts that SafePoint
- thread safe - I don't understand why. I don't see happens before that guarantee this. After constructor termination, another thread can see SafePoint
instance underconstructed.
example:
SafePoint racePublishedSafePoint; //field
//thread 1:
racePublishedSafePoint = new SafePoint(1,1);
//thread 2:
SafePoint sp;
while(true){
SafePoint sp = racePublishedSafePoint;
if(sp != null) break;
}
System.out.println(sp.get()[0]);
System.out.println(sp.get()[1]);
I believe that there is several posiiblle outcomes:
- application doesn't finish
else if application finished - we can see
a) 0 0
b) 0 1
c) 1 0
d) 1 1
Am I right?
If true, why author marked class as thread safe?
I thought that thread-safe class - class which can be used in concurrent application without sophisticated analyze.
What did author want to say?
Also in book I have read following note:
The private constructor exists to avoid the race condition that would occur if the copy constructor were implemented as this(p.x, p.y); this is an example of the private constructor capture idiom (Bloch and Gafter, 2005).
It is not clear for me too.
why we need 3 constructors and one of them private?
Please clarify these things.