Java final & Safe Publication - PullRequest
       53

Java final & Safe Publication

0 голосов
/ 24 апреля 2018

Когда я прочитал jsr-133-faq на вопрос «Как работают последние поля в новом JMM?», Он сказал:

class FinalFieldExample {
  final int x;
  int y;
  static FinalFieldExample f;
  public FinalFieldExample() {
    x = 3;
    y = 4;
  }
  static void writer() {
    f = new FinalFieldExample();
  }
  static void reader() {
    if (f != null) {
      int i = f.x;
      int j = f.y;
    }
  }
}

КлассВыше приведен пример того, как должны использоваться последние поля.Читатель, выполняющий поток, гарантированно увидит значение 3 для fx, потому что оно является окончательным.Не гарантируется увидеть значение 4 для y, потому что оно не является окончательным.

Это сбивает меня с толку, поскольку код в средстве записи не является безопасной публикацией, читатель, выполняющий поток, может увидеть, что f неnull, но конструктор объекта, на который ссылается f, еще не завершен, поэтому, даже если x является окончательным, поток, выполняющий читатель, не может быть уверен, что увидит значение 3 для fx

Это место, где яЯ в замешательстве, пожалуйста, поправьте меня, если я ошибаюсь, большое спасибо.

1 Ответ

0 голосов
/ 28 мая 2018

В этом весь смысл, и это то, что хорошо в финальных полях в JMM. Да, компилятор, как правило, может назначить ссылку на объект еще до того, как объект будет полностью построен, и это публикация небезопасная , поскольку доступ к объекту может быть выполнен в частично созданном состоянии. Однако для полей final JMM (и компилятор) гарантирует, что все конечные поля будут подготовлены first , перед назначением ссылки на объект. Публикация может все еще быть небезопасной, и объект все еще только частично создан, когда новый поток обращается к нему, но по крайней мере последние поля будут в ожидаемом состоянии. Из главы 16.3 «Практический параллелизм Java»:

Безопасность инициализации делает гарантии видимости только для значений которые доступны через конечные поля на момент конструктора отделки. Для значений, достижимых через нефинальные поля, или значений, которые может измениться после строительства, вы должны использовать синхронизацию, чтобы обеспечить видимость.

Я также рекомендую прочитать главу 16.3 для более подробной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...