![](/img/trans.png)
[英]Reordering in case two synchronized block and multiple volatile read/write
[英]Why reordering takes place with two volatile variables?
我正在嘗試調查Java環境中的重新排序行為(使用JDK 9-ea + 170),發現有一件我自己無法解釋的事情,因此,我將很高興聽到一些有關它的注釋。 這是一個例子:
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);
}
}
該程序具有一個test()
方法,該方法僅遞增x和y值。 我正在創建新的線程並調用此test()
直到某些內部Java優化未更改x++; y++;
的順序x++; y++;
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);
}
}
該程序永遠不會結束,因為volatile保證volatile之前的所有指令都將被刷新到內存中,因此x++;
總是在y++;
之前執行y++;
並且不可能使y> x。 根據我的理解,這也是可以預期的。 但是之后,我在int x;
添加了volatile int x;
我現在也可以再次看到重新排序,所以程序大多數時間結束:
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);
}
}
為什么還要在這里進行重新排序?
這不是重新排序的證據。 實際上,發生的事情是由於volatile
上的++
不是原子的。 例如,在更新變量( x
)之一時,請考慮以下兩個線程( A
和B
)對操作的交織:
thread A: load x -> temp
thread B: load x -> temp
thread A: temp = temp + 1
thread B: temp = temp + 1
thread A: save temp -> x
thread B: save temp -> x
並且如果您通過這種交錯處理這些操作,您會發現您對x
失去了計數。 這足以使cy <= cx
偶爾失敗。
( y
也會發生“計數丟失”行為,這解釋了為什么該實驗有時會失敗。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.