Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading private constructor

Straight out from Java concurrency in Practice :

@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;
  }
}

The above is a Thread-safe class : since its setters are synchronized. I understand also why the getter doesn't individually return x / y but instead returns an array. I have 2 questions . Why ?

  1. private SafePoint(int[] a)
  2. public SafePoint(SafePoint p) { this(p.get()); } instead of this(p.x,p.y);
like image 437
Achow Avatar asked Dec 20 '12 10:12

Achow


1 Answers

Because calling this(p.x, p.y) is not atomic. In other words, imagine the following thread interleaving:

  • Thread1: read p.x
  • Thread2: p.set(otherX, otherY);
  • Thread1: read p.y and call this(p.x, p.y);

The x and the y are now from two different points and possibly not consistent.

On the other hand, p.get() reads x and y atomically (it is synchronized) and therefore guarantees that the x and the y in the array are from the same point.

like image 95
assylias Avatar answered Sep 23 '22 22:09

assylias