Java: непостоянные подразумеваемые гарантии порядка

Мой вопрос является расширением этого: Неустойчивые гарантии и выполнение вне очереди

Чтобы сделать его более конкретным, скажем, у нас есть простой класс, который может быть в двух состояниях после инициализации:

class A {
    private /*volatile?*/ boolean state;
    private volatile boolean initialized = false;

    boolean getState(){
        if (!initialized){
            throw new IllegalStateException();
        }
        return state;
    }

    void setState(boolean newState){
        state = newState;
        initialized = true;
    }
}

Поле initialized объявлено изменчивым , поэтому оно вводит «барьер», который предотвращает переупорядочение. Поскольку поле состояния записывается только до записи инициализированного поля и только для чтения после инициализированное поле считывается, I может удалить ключевое слово volatile из объявления состояния и по-прежнему никогда не видеть устаревшее значение. Вопросы:

  1. Правильно ли это рассуждение?
  2. Гарантируется ли, что поле записи в инициализированное не будет оптимизировано (так как оно изменяется только в первый раз) и «барьер» победит «не потеряно?»
  3. Предположим, что вместо флага в качестве инициализатора использовался CountDownLatch :

     class A {
    private / * volatile? * / boolean состояние; 
    частный финал CountDownLatch initialized = new CountDownLatch (1); 
     
    логическое getState () выбрасывает InterruptedException {
    initialized.await (); {{1} } return state; 
    } 
     
    void setState (boolean newState) {
    state = newState; 
    инициализировано.countdown (); 
    } 
    } 
     

    Все будет хорошо?

23
задан Community 23 May 2017 в 12:15
поделиться