Мой вопрос касается безопасной публикации значений полей в Java (как описано здесь многопоточность и безопасная публикация Java).
Как я понимаю, поле можно безопасно читать (это означает, что доступ из нескольких потоков будет видеть правильное значение), если:
- чтение и запись синхронизируются на одном мониторе Поле
- является окончательным. Поле
- нестабильно
Если мое понимание верное, следующий класс должен не быть потокобезопасным, так как начальное значение записывается без этих характеристик. Однако мне трудно поверить, что мне нужно сделать first
volatile
, хотя он доступен только из метода synchronized
.
public class Foo {
private boolean needsGreeting = true;
public synchronized void greet() {
if (needsGreeting) {
System.out.println("hello");
needsGreeting = false;
}
}
}
Я что-то упустил? Правильно ли указан код и если да, то почему? Или необходимо в таких случаях сделать first
volatile
или использовать final AtomicBoolean
или что-то вроде этого дополнительно для доступа к нему из метода synchronized
.
(Чтобы уточнить, я знаю, что если начальное значение было записано в методе synchronized
, оно было бы потокобезопасным даже без ключевого слова volatile
.)