私は正確に起こる、前に何不動産手段にいくつかの明確さをしたいと思います。
私はたまたま、前のプロパティと言う彼らは、Aの中に揮発性のある他のいくつかの変数の前に変更または変更された場合(揮発性またはシンクブロックで囲まれていない)グローバル変数への更新は、他のスレッドに可視にしていることについての説明を見てきましたシンクブロック。これは正しいですか?もしそうなら、どこJavaドキュメントではこれを言うのでしょうか?
:私の理解では、たまたま-前にプロパティが共有フィールドとコード実行などの間の関係を定義するということでした
- モニターのロック解除が起こり、前に同じモニターの後続のすべてのロック。
- volatileフィールドへの書き込みが起こり、前に同じフィールドのすべての後続の読み取り。
- スレッド上で開始するコールが起き、前に開始されたスレッド内のアクション。
- スレッド内のすべてのアクションが起こる前に、他のスレッドが正常にそのスレッドに参加するから返します。
例えば:
class Shared {
private int y = 0;
private volatile int x = 0;
public void setOne() {
y = 1;
x = 1;
}
public int getY() {
return y;
}
}
上記のコードのために、2つのスレッド所与。
Shared shared = new Shared();
new Thread(() -> shared.setOne()).start();
new Thread(() -> shared.getY()).start();
編集我々は最初のスレッドが開始されたことを保証できると仮定すると、希望のgetY()の戻り0またはここ1?
私はまた、この動作は、スレッドだけで揮発性のフィールドの読み取り、次起こるという例を見てきました。1つのスレッドがvolatileフィールド(LETの言うスレッドB)の値を読み込む場合、私は内のgetY()メソッドを変更するのであれば、その場合には、その後、スレッドAにその揮発性のフィールドの前に書かれたすべてのフィールドは、B.このよるスレッドにご利用いただけますされるように上からオブジェクトを共有:
public int getXPlusY() {
int local = x;
return local + y;
}
それは、他のスレッドにyが表示されるようになり、このアクションですか?
最初の2番目の例で見てみましょう。
class Shared {
private int y = 0;
private volatile int x = 0;
public void setOne() {
y = 1; //(1)
x = 1; //(2)
}
public int getXPlusY() {
int local = x; //(3)
return local + y; //(4)
}
}
私たちはそこにあることを知って起こる-前に起因して(1)との間の関係は、(2)プログラムの順序:
xとyが同じスレッドの行為であり、xはプログラム順にyの前に来る場合は、(x、y)をHB。
以来x
揮発性である、我々はそこだということを知って起こる-前に(2)と(3)との間の関係
揮発性フィールド(§8.3.1.4)への書き込みが起こる-前に、そのフィールドのすべての後続の読み取り。
とがある起こる-前(3)と(4)との間の関係に起因して、プログラム順序再び:
xとyが同じスレッドの行為であり、xはプログラム順にyの前に来る場合は、(x、y)をHB。
したがって、我々は事前発生チェーン(1)→(2)、(2)→(3)、(3)→(4)
それ以来発生し、前推移関係は(B及びBがCの前に発生する前にAが発生した場合、AがCの前に起こる)であることを意味することをことを(1)が発生し、前(4)との関係。
今度は、最初の例を見てみましょう:
class Shared {
private int y = 0;
private volatile int x = 0;
public void setOne() {
y = 1; //(1)
x = 1; //(2)
}
public int getY() {
return y; //(3)
}
}
再びあります前に、たまたま(1)及び(2)の間の関係が、それはそれについてです。以来、x
第二のスレッドによって読み取られていない、我々は全くありません事前発生(2)及び(3)の間です。したがって、我々は全く起こらない、前(1)および(3)の関係。
引用はから採取されたJava言語仕様の第17章(JLS)