重要な編集2つの割り当てが行われているスレッドの「前に起こる」について知っています。私の質問は、 「a」がまだnullである間に、別のスレッドが「b」をnull以外で読み取る可能性があるかどうかです。したがって、以前にsetBothNonNull(...)を呼び出したスレッドと同じスレッドからdoIt()を呼び出している場合、NullPointerExceptionをスローすることはできません。しかし、setBothNonNull(...)を呼び出すスレッドとは別のスレッドからdoIt()を呼び出す場合はどうなるでしょうか。
この質問はvolatile
キーワードとvolatile
保証に関するものであることに注意してください。キーワードに関するものではありません(したがって、解決する問題がないため、「同期を使用する必要があります」と答えないでください。単に保証synchronized
を理解したいだけです。volatile
(または保証の欠如)アウトオブオーダー実行に関して)。
volatile
コンストラクターによってnullに初期化される2つの文字列参照を含むオブジェクトがあり、2つの文字列を変更する方法は1つしかないとします。つまり、 setBoth(...)を呼び出し、後でそれらの参照を非に設定することしかできません。 null参照(コンストラクターのみがそれらをnullに設定できます)。
たとえば(これは単なる例であり、まだ質問はありません):
public class SO {
private volatile String a;
private volatile String b;
public SO() {
a = null;
b = null;
}
public void setBothNonNull( @NotNull final String one, @NotNull final String two ) {
a = one;
b = two;
}
public String getA() {
return a;
}
public String getB() {
return b;
}
}
setBothNoNull(...)では、非nullパラメータ「a」を割り当てる行が非nullパラメータ「b」を割り当てる行の前に表示されます。
次に、これを行うと(もう一度、質問はありません。質問は次に来ます):
doIt() {
if ( so.getB() != null ) {
System.out.println( so.getA().length );
}
}
アウトオブオーダー実行のためにNullPointerExceptionが発生する可能性があることを理解していますか?
言い換えると、null以外の「b」を読み取ったためにnull以外の「a」を読み取るという保証はありませんか?
アウトオブオーダー(マルチ)プロセッサとvolatile
動作方法により、「a」の前に「b」を割り当てることができますか?
volatile
書き込みに続く読み取りは常に最後に書き込まれた値を参照することを保証しますが、ここには順序が正しくない「問題」がありますか?volatile
(繰り返しになりますが、「問題」は、問題を解決するためではなく、キーワードとJavaメモリモデルのセマンティクスを理解しようとすることを目的としています)。