Почему SafePoint threadSafe?(Параллелизм на практике)

Я читаю параллелизм на практике.
Есть следующий пример (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;
    }
}

Автор действует, что SafePoint - Поток безопасно - я не понимаю, почему. Я не вижу, что происходит до того, как это гарантировать. После завершения конструктора другой поток может видеть SafePoint экземпляр недооценен.

пример:

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]);

Я считаю, что есть несколько возможных результатов:

  1. приложение не заканчивается
    иначе, если приложение завершено
  2. мы можем увидеть
    а) 0 0
    б) 0 1
    в) 1 0
    г) 1 1

Я прав?
Если это правда, почему автор отметил класс как потокобезопасный? Я думал, что потокобезопасный класс - класс, который можно использовать в параллельном приложении без сложного анализа.

Что хотел сказать автор?


Также в книге я прочитал следующую заметку:

Закрытый конструктор существует, чтобы избежать состояния гонки, которое могло бы возникнуть, если бы конструктор копирования был реализован так (px, py); это пример идиомы захвата частного конструктора (Bloch and Gafter, 2005).

Это мне тоже не понятно.

зачем нам 3 конструктора и один из них приватный?

Пожалуйста, уточните эти вещи.

0 ответов

Другие вопросы по тегам