public class testVolatile {
private int i = 0;
// a線程調用
public void foo1() {
try {
while (true) {
Thread.sleep(10);
System.out.println("第一個:" + i);
i++;
}
} catch (InterruptedException e) {
// not to do;
}
}
// b線程調用
public void foo2() {
try {
while (true) {
Thread.sleep(10);
System.out.println("第二個:" + i);
}
} catch (InterruptedException e) {
// not to do;
}
}
public static void main(String[] args) {
final testVolatile test = new testVolatile();
// 線程1
new Thread() {
public void run() {
test.foo1();
}
}.start();
// 線程2
new Thread() {
public void run() {
test.foo2();
}
}.start();
}
}
輸出結果如下:
第一個:0
第二個:1
第一個:1
第二個:2
第一個:2
第二個:3
第一個:3
第二個:4
第一個:4
第二個:5
第一個:5
第二個:6
第一個:6
第二個:7
第一個:7
第二個:8
第一個:8
第二個:9
第一個:9
第二個:10
第一個:10
變量i增加volatile 關鍵字後如下
第二個:0
第一個:0
第二個:1
第一個:1
第二個:2
第一個:2
第二個:3
第一個:3
第二個:4
第一個:4
第二個:5
第一個:5
第二個:6
第一個:6
第二個:7
第一個:7
第二個:8
第一個:8
第二個:9
第一個:9
第二個:10
求高人指點,變量 i 沒有增加 volatile 關鍵字時,第二個輸出為什麼會隨著第一個i 的變化而變化?
你需要了解volatile關鍵字作用,一個定義為volatile的變量,它將具備兩種性質:第一是保證此變量對所有線程的可見性,即當一個線程修改了這個變量後,這個新值對於其他線程來說是立即可見的。第二就是保證不進行指令重排序。
所以,你沒有添加volatile關鍵字,多線程同時修改變量可能某個線程讀到的數據不是最新值,即你的第一個輸出結果體現了某個時刻線程1,2同時讀到了數值1時,此時線程2可能已經修改了變量。所以導致了不正確的結果。