public class SimpleVolatile1 {
static class BossThread {
public volatile int age = 30;
public void execBirth(){
age++;
System.out.println("boss.age++");
}
public void print(){
while(age < 31) {
System.out.println(age);
}
}
}
public static void main(String[] args){
BossThread bt = new BossThread();
for(int i=0; i<10; i++){
new Thread(bt::print).start();
}
new Thread(bt::execBirth).start();
}
}
在我的電腦上某次輸出的結果是
30
30
30
30
boss.age++
30
30
30
30
30
30
按照 volatile 關鍵字的功能,當一個共享變數被標記為 volatile 時,它不應該會出現臟讀現象,但我的測驗程式里,boss.age++ 被列印出來之后,有些執行緒依然讀到的是舊值!
有人能給解釋一下嗎!
謝謝!
uj5u.com熱心網友回復:
這是代碼處理的原子性造成的。假設print執行緒判斷while(age<31)成立進入回圈,剛想執行System.out.println(30)的時候(這里println的引數傳遞完畢,但是列印處理還沒來得及執行的時候),cpu占用權被識訓,輪到execBirth執行緒執行,execBirth執行緒執行完后,輪到print執行緒執行,這樣print執行緒依然會列印30(之前println(30)引數都傳好了,只是沒來得及列印),所以最終就是你現在這樣的結果。
所以,這個和volatile沒關系,是代碼處理的原子性造成的。
uj5u.com熱心網友回復:
你的定義是:public volatile int age = 30; 它不是一個共享的靜態變數,每個物件實體中,都有一個此變數你在回圈中啟動了10個實體,列印了10個30,回圈外的執行緒執行了execBirth,列印了boss.age++。你的執行結果都會是這樣,只是boss.age++前后位置有少許不同
正確定義方式是:static volatile int age= 30;
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/162115.html
標籤:Java SE
上一篇:2020-10-07:redis存在執行緒安全的問題嗎?為什么?
下一篇:Python 使用 asyncio 時出現 RuntimeError: This event loop is already running 的解決方法
