Безопасен ли синхронизированный доступ к энергонезависимым полям?
Я не могу найти ответ на этот конкретный сценарий в любом месте.
Если я позвоню init()
одновременно из двух потоков, один из вызовов гарантированно увидит, что time
больше не равно нулю? Есть ли time
нужно быть volatile
также?
Это работает как join()
какая точка синхронизации?
private Long time;
synchronized void init() {
if (time != null) {
throw new IllegalStateException("Already initialised.");
}
this.time = System.currentTimeMillis();
}
2 ответа
Когда поток входит в это synchronized
метод, он приобретает implicit
заблокировать экземпляр, изменения, которые он выполняет в state
экземпляра виден другим потокам, ожидающим входа в синхронизированный метод.
при выходе из синхронизированного метода он автоматически устанавливает отношение "до и после" с любым последующим вызовом синхронизированного метода для того же объекта. Это гарантирует, что изменения состояния объекта видны всем потокам.
Последняя строка в документах ясно говорит об этом. Неважно, если бы государство volatile
или же non-volatile
,
Более простое решение - использовать инициализатор статического класса.
class TimeHolder {
public static final long time = System.currentTimeMillis ();
}
Предполагается, что вы инициируете, когда класс используется в первый раз или когда объект создан.