私はJava環境(JDK 9-ea + 170を使用)で並べ替えの動作を調べようとしていますが、自分では説明できないものがあることが分かりました。ここでの例は次のとおり並べ替えが2つの揮発性変数で行われるのはなぜですか?
public class Client {
int x;
int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}
このプログラムは単にxとyの値をインクリメントtest()
方法を有しています。いくつかの内部Java最適化が変更されない限り、新しいスレッドを作成してtest()
と呼びます。x++; y++;
命令の順序()。このようにして、並べ替えが実際に行われることが証明されます。プログラムはほとんどの場合終了します(これは予想されます)。 は、今私は、yにvolatile修飾子を追加しました:
public class Client {
int x;
volatile int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}
揮発する前にすべての命令がメモリにフラッシュされることを揮発性の保証はそうx++;
は常にy++;
前に実行し、それを持ってすることはできませんので、このプログラムが終了することはありませんy> xである。これは私の理解からも期待されます。プログラムは、ほとんどの時間を終了してしかし、私はあまりにも、今int x;
に揮発追加したことの後に私は再びreorderingsを見ることができます:
public class Client {
volatile int x;
volatile int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}
並べ替えもここで行われるのはなぜ?
あなたはB> Aということが可能です方法の例を提供していただけますか? 上記で説明したフローでは、Aへの代入はBへの代入の前に行われます。 –
1)変数は 'x'と' y'です。 「A」および「B」はスレッドを示す。 2)起こる必要があることは、あなたが 'y'で行うよりも' x'で多くのカウントを失うことです、そして 'y <= x'は' false'になります。 –
ありがとうございました!今は私のために少し清潔です。スティーブン、今私は同じコードを実行しているが、test()上でsynchronizedキーワードを使用しています。それは、volatileがyまたはxとyにあるときにはうまくいくが、volatile(期待される)なしでは失敗し、xのみでvolatileで失敗する。それは正常な行動ですか?何が起こっているか知っているかどうかを説明してください。 –