セルゲイGornostaev:
public class ReOrdering implements Runnable { int one, two, three, four, five, six; volatile int volaTile; @Override public void run() { one = 1; two = 2; three = 3; volaTile = 92; int x = four; int y = five; int z = six; } }
割り当て
one
、two
およびthree
限り、彼らはすべての前に起こるように、並べ替えすることができるvolatile
の書き込み。同様に、x
、y
、およびz
などの文を並べ替えることもvolatile
書き込みがそれらのすべての前に起こります。volatile
操作はしばしば呼ばれるメモリバリア。読み取りと書き込み指示することを保証性を保証する前に発生したvolatile
変数は全体並べ替えることができないメモリバリア。場合は、スレッドへの書き込みへ:保証は別の効果を持つ前に起こる
volatile
非揮発性物質を含む- -に書き込む前にスレッドによって変更され、他のすべての変数の変数、volatile
変数はまた、メインメモリにフラッシュされます。スレッドが読み取るとvolatile
、不揮発性を含む- -と一緒にメインメモリにフラッシュされた変数を、それはまた、他のすべての変数読み込みvolatile
変数を。
©ブルースEckel氏 "上のJava 8"
このコードは次のように動作しませんので、私は誤解の何かを持っている必要があります
public class Reordering {
private int x;
private volatile int y;
public void writer() {
x = 1;
y = 2;
}
public void reader() {
if (y == 2) {
if(x == 0) {
// X assignment is happens-before for
// volatile Y assignment
// so X can't be 0 when Y equals 2
throw new RuntimeException();
}
x = 0;
y = 0;
}
}
public static void main(String[] args) {
Reordering reordering = new Reordering();
Thread thread = new Thread(() -> {
while (true) {
reordering.writer();
}
});
thread.setDaemon(true);
thread.start();
while (true) {
reordering.reader();
}
}
}
TmTron:
私はライタートレッドがちょうどセットを持っているとき、問題が発生することができると思うx=1
読者がもしブロック(変数の代入前)に既に存在する一方で、:
reader writer state
----------------- ------ --------
stops before x=0 x=1, y=2
x=1 x=1, y=2
x=0 x=0, y=2
y=0 x=0, y=0
y=2 x=0, y=2
reader will throw