Я хочу убедиться, что я правильно понимаю поведение "Эффективно неизменяемых объектов" в соответствии с моделью памяти 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 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 Memory Model гарантирует, что все потоки ДОЛЖНЫ иметь Outworld.published.get() == 3
?
Согласно Java Concurrency In Practice, это должно быть правдой, но, пожалуйста, исправьте меня, если я неправильно.
3.5.3. Безопасные публикации Идиомы
Чтобы безопасно опубликовать объект, как ссылка на объект, так и состояние объекта должно быть видимым для других потоков одновременно. Правильно построенный объект можно безопасно опубликовать:
- Инициализация ссылки на объект из статического инициализатора; - Сохранение ссылки на него в поле volatile или AtomicReference; - Сохранение ссылки на него в конечное поле правильно построенного объекта; или
- Сохранение ссылки на него в поле, которое должным образом защищено блокировкой.3.5.4. Эффективно неизменяемые объекты
Безопасно опубликованные эффективно неизменяемые объекты могут безопасно использоваться любой поток без дополнительной синхронизации.