[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 13433] コンストラクタ内で初期化するフィールドの可視性(宿題)



高橋(徹)です。

◯宿題
  コンストラクタ内で初期化するフィールドは、その後別スレッドが実行する
インスタンスメソッド内で無条件に可視であるか?

について、Java言語仕様第3版をあたると、17.5 finalフィールドのセマンティックスに、

「オブジェクトは、そのコンストラクタが完了した時点で完全に初期化されたと考えられる。
オブジェクトが完全に初期化された後のオブジェクトに対する参照のみを観測することが
できるスレッドは、該当オブジェクトのfinalフィールドの初期値を正しく観測できることが
保障されている。」

とあります。これによれば、finalなフィールドであれば宿題の問いにYES、非finalな
フィールドであればNOとの回答となります。

また、同書の17.5節にある2つの考察の1つ目には、以下の記述があります。
「writer()は該当オブジェクトのコンストラクタが完了した後、fに対する書き込みを
行うため、reader()は正しく初期化されたf.xの値、つまり3を観測することが保障される。
しかし、f.yはfinalでないため、reader()メソッドは値4を観測することが保障されない。」

この説明の前にサンプルコードがありますが、
http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.5
を参照してください。

このサンプルコードを、6コアのPCで6スレッド生成して動かしてみましたが
やはりというか予想通りというか、非finalフィールドの値は初期化後のもの
しか観測できませんでした。難しいですね。