Practice-オブジェクトのfinalとしてフィールドを作成すると、そのオブジェクトのnull参照を参照するスレッドは避けられますか?
でのJava並行処理から抽象/スニペット// Unsafe publication
public Holder holder;
public void initialize(){
holder = new holder(42);
}
2つのことは、不適切に発行されたオブジェクトと間違って行くことができます。他の スレッドはホルダーフィールドの無効な値を参照する可能性があり、値が の場合でも、 null参照または他の古い値を参照してください。しかし、他のスレッドでは、の最新の という値が表示されますが、 ホルダーの状態では無効です。状況をさらに予測しにくくするために、スレッドは が最初にフィールドを読み取ったときに失効した値を表示し、次に の値を返します。なぜassertSanityが AssertionErrorを投げることができるのですか。
は、基準は、別のスレッドに可視となるオブジェクトは、必ずしも、そのオブジェクトの状態が消費スレッド Ofcouse、それを修正する方法の一つは次のようになり
public class Holder{
private int n;
public Holder(int n) {
this.n = n;
}
public void assertSanity(){
if (n != n)
throw new AssertionError("This statement is false.");
}
}
に表示されていることを意味しません行うには/作る
public volatile Holder holder;
著者は
異なる的アプローチを提案していますホルダーが不変であれば、assertSanityはホルダーが適切に公表されなかった場合でも、 てAssertionErrorを投げることができませんでした。)
public class Holder{
private final int n;
//...
}
しかし、どのように?安全でない出版物はまだそこにあります。スレッドではまだnullの参照が得られていると思います。提案してください。
関連http://stackoverflow.com/questions/16107683/improper-publication-of-java-object-reference and http://stackoverflow.com/a/6088679/1743880 – Tunaki