Я хочу убедиться, что правильно понимаю поведение «эффективно неизменяемых объектов» в соответствии с моделью памяти Java.
Допустим, у нас есть изменяемый класс, который мы хотим опубликовать как эффективно неизменяемый:
class Outworld {
// This MAY be accessed by multiple threads
public static volatile MutableLong published;
}
// This class is mutable
class MutableLong {
private long value;
public MutableLong(long value) {
this.value = value;
}
public void increment() {
value++;
}
public long get() {
return value;
}
}
Мы делаем следующее:
// Create a mutable object and modify it
MutableLong val = new MutableLong(1);
val.increment();
val.increment();
// No more modifications
// UPDATED: Let's say for this example we are completely sure
// that no one will ever call increment() since now
// Publish it safely and consider Effectively Immutable
Outworld.published = val;
Вопрос:
Гарантирует ли модель памяти Java, что все потоки ДОЛЖНЫ иметь Outworld.published.get() == 3
?
СогласноJava Concurrency In Practiceэто должно быть правдой, но, пожалуйста, поправьте меня, если я ошибаюсь.
3.5.3. Идиомы безопасной публикации
Для безопасной публикации объекта и ссылка на объект, и состояние объекта должно быть сделано видимым для других потоков одновременно. Правильно сконструированный объект можно безопасно опубликовать с помощью:
-Инициализации ссылки на объект из статического инициализатора;
-Сохранение ссылки на него в volatile поле или AtomicReference;
-Сохранение ссылки на него в конечном поле корректно сконструированного объекта; или
-Сохранение ссылки на него в поле, которое должным образом защищено блокировкой.3.5.4. Эффективно неизменяемые объекты
Безопасно опубликованные эффективно неизменяемые объекты могут безопасно использоваться любой поток без дополнительной синхронизации.