Безопасная публикация без происшествий? Во всяком случае, кроме финала?

Согласно JCP (16.2.2. Безопасная публикация):

Это происходит до того, как гарантия на самом деле является более сильным обещанием наглядности и упорядоченности, чем безопасное издание. Когда X безопасно публикуется от A до B, безопасная публикация гарантирует видимость состояния X, но не состояния других переменных, которые могли коснуться. Но если A помещает X в очередь - до того, как B извлекает X из этой очереди, B не только видит X в состоянии, в котором A его покинул (при условии, что X не был впоследствии изменен A или кем-либо еще), но B видит все, что А делал перед передачей (опять же, с учетом того же предостережения)

Я задаюсь вопросом, когда безопасная публикация может быть без предшествующего события, то есть без использования volatile / atomics или синхронизации (или через структуры, такие как AQS, которые используют любой из перечисленных внутри)?

Один случай - заключительные поля в неизменяемом объекте, где вы можете опубликовать его без каких-либо дополнительных шагов.

Есть ли другие случаи?

UPD: перечитайте 3.5.3. Безопасная публикация идиом, другой случай - "Инициализация ссылки на объект из статического инициализатора". Кажется, теперь это все варианты.

3 ответа

Решение

Я ничего не знаю, кроме finalи взгляд на http://java.sun.com/docs/books/jls/third_edition/html/memory.html кажется, подтверждает это. Глава 17.4 посвящена всему, кроме final, что объясняется отдельно в 17.5.

Следует отметить, однако, что все, что находится внутри JVM, всегда должно быть видно, прежде чем это может способствовать гонке данных в коде Java. Это затрагивает в основном длины массивов, указатели виртуальных таблиц и содержимое строк. Они никогда не могут рассматриваться как неинициализированные или иным образом противоречивые.

Весь список случаев, которые вы можете найти в Java In Concurrency:

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

Инициализация ссылки на объект из статического инициализатора;

Сохранение ссылки на него в энергозависимом поле или AtomicReference;

Сохранение ссылки на него в конечном поле правильно построенного объекта; или же

Сохранение ссылки на него в поле, которое должным образом охраняется блокировкой.

Статическая инициализация выполняется внутри synchronized(class)так что это очень сильно.

в то время как final семантика слабее, я сомневаюсь, что реализация действительно так слаба.

У Дуга Ли было предложение по более примитивным заборам, http://cs.oswego.edu/pipermail/concurrency-interest/2009-January/005743.html

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