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は初期化後に値を畳み込める。
確実な1回実行
サプライヤは競合状態でも必ず1回だけ実行されます。
旧来のアプローチ
ダブルチェックロッキング
モダンなアプローチ
StableValue
JDKバージョン
25
難易度
上級
JDKサポート
安定した値
プレビュー
JDK 25でプレビュー(JEP 502)。--enable-previewが必要です。
仕組み
StableValueは組み込みのスレッド安全性を持つ遅延初期化されたイミュータブルな値を提供します。ダブルチェックロッキング、volatileフィールド、synchronizedブロックは不要です。JVMは初期化後の読み取りパスを最適化することもできます。
関連ドキュメント