Java 言語仕様では、セクション 17.5で final フィールドのセマンティクスを定義しています。
final フィールドの使用モデルは単純なものです。オブジェクトのコンストラクターでオブジェクトの最終フィールドを設定します。オブジェクトのコンストラクターが終了する前に、別のスレッドが参照できる場所に構築中のオブジェクトへの参照を書き込まないでください。これに従えば、オブジェクトが別のスレッドから見られるとき、そのスレッドは常に、そのオブジェクトの final フィールドの正しく構築されたバージョンを認識します。また、少なくとも最終フィールドと同じくらい最新の最終フィールドによって参照されるオブジェクトまたは配列のバージョンも表示されます。
私の質問は - 「最新」の保証は、ネストされた配列とネストされたオブジェクトの内容にまで及びますか?
簡単に言うと、1 つのスレッドが可変オブジェクト グラフをオブジェクトの final フィールドに割り当て、オブジェクト グラフが更新されない場合、すべてのスレッドが final フィールドを介してそのオブジェクト グラフを安全に読み取ることができますか?
シナリオ例:
- スレッド A は ArrayLists の HashMap を構築し、その HashMap をクラス「MyClass」のインスタンスの最終フィールド「myFinal」に割り当てます。
- スレッド B は、MyClass インスタンスへの (非同期の) 参照を確認し、「myFinal」を読み取り、ArrayLists の 1 つの内容にアクセスして読み取ります。
このシナリオでは、スレッド B から見た ArrayList のメンバーは、少なくとも MyClass のコンストラクターが完了したときと同じくらい最新であることが保証されていますか?
同期などの代替ソリューションではなく、Java メモリ モデルと言語仕様のセマンティクスの明確化を求めています。私の夢の答えは、関連するテキストを参照して、はいまたはいいえです。
アップデート:
- Java 1.5 以降のセマンティクス、つまり JSR 133 で導入された更新された Java メモリ モデルに興味があります。最終フィールドの「最新」の保証は、この更新で導入されました。