Stable Values
Потокобезопасная ленивая инициализация без volatile или synchronized.
Сравнение кода
✕ Java 8
private volatile Logger logger;
Logger getLogger() {
if (logger == null) {
synchronized (this) {
if (logger == null)
logger = createLogger();
}
}
return logger;
}
✓ Java 25 (Preview)
private final StableValue<Logger> logger =
StableValue.of(this::createLogger);
Logger getLogger() {
return logger.get();
}
Заметили проблему в этом коде? Сообщите нам.
Почему современный подход лучше
Нулевой шаблонный код
Никаких volatile, synchronized или проверок на null.
Оптимизировано JVM
JVM может свернуть значение после инициализации.
Гарантировано однократное выполнение
Supplier выполняется ровно один раз, даже при конкуренции.
Старый подход
Двойная проверка блокировки
Современный подход
StableValue
Начиная с JDK
25
Сложность
Продвинутый
Поддержка JDK
Stable Values
Предварительный просмотр
Preview в JDK 25 (JEP 502). Требует --enable-preview.
Как это работает
StableValue предоставляет лениво инициализируемое неизменяемое значение со встроенной потокобезопасностью. Никакой двойной проверки блокировки, volatile-полей, synchronized-блоков. JVM может даже оптимизировать путь чтения после инициализации.
Связанная документация
Доказательство