日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

为什么不使用volatile,其它线程也能得到当前线程修改后的值,不使用volatile也不存在可见性问题?原来解决可见性问题不一定需要volatile,println也可以

發布時間:2025/3/19 编程问答 34 豆豆

1. 為什么不使用volatile,其它線程也能得到變量修改后的值

實驗代碼分析

①初始變量a=true,b=false;

②一個線程判斷a或者b是否被改為相應邏輯,如果是,那么輸出信息。

③修改a和b的線程。

實驗結果分析:不是說沒有volatile修飾的變量存在可見性問題嗎,怎么可以得到另一個線程修改的值,不存在可見性問題嗎??

原因:其實可見性問題的造成就是因為各自從緩存取數據,而不從內存取數據,如果緩存都沒有數據,大家都使用內存的值,那么就不存在可見性問題。這里不存在可見性問題的原因就是當前變量還沒有被放入緩存,我們可以加上一點休眠,讓程序有時間把數據放入緩存,然后測試,如下。

其它博客有提到,說在線程中使用的睡眠會釋放cpu執行權,然后CPU有時間去更新工作緩存和主存內容。那我這邊通過一個簡單的for循環,讓CPU沒有時間去同步緩存和主存。

2. 為什么不使用volatile,其它線程還能得到變量修改后的值

實驗代碼分析

① 初始變量a=0,b=false;

②然后,一個線程判斷?b 的值是否為false,是false那么循環輸出“b is false and a is ”信息,直到 b 的值變為true,輸出“b is true and a is”信息結束線程;

③然后延遲2ms,為了讓后面的線程晚于前面線程執行;

④最后,另一個線程會修改a=1,b=true。

實驗結果分析:首先控制臺輸出了一句“b is false and a is 0”,因為初始值a=0,b=false,所以正確;但是后面控制臺輸出了一句“b?is true and a is 1”,為什么???不是說沒有volatile修飾的變量是會存在可見性問題的嗎?不是說一個線程修改的值,其它線程是得不到修改后的值嗎??怎么這邊能得到呢?

在分析之前,我們需要記住兩點:第一,并發編程存在可見性問題;第二:可見性問題并不是只能通過volatile修飾來解決,也就是說——沒有volatile修飾的變量不一定存在可見性問題

原因:既然并發編程存在可見性問題,而且這邊沒有volatile修飾,那么可見性問題是怎么解決的呢?其實這邊可見性問題是通過System.out.println語句解決的,也就是System.out.println語句觸發了MESI緩存一致性協議。我們這邊將System.out.println注釋后,運行結果出現了可見性問題,可驗證原先是System.out.println解決了可見性問題,運行結果及分析如下。

3. 其實System.out.println是通過synchronized關鍵字觸發MESI緩存一致性協議,從而解決可見性問題,如下圖。

總結:發生可見性問題,需要兩個條件,①各線程操作數據是在緩存中操作,才會存在緩存不一致;②沒有觸發緩存一致性協議。

總結

以上是生活随笔為你收集整理的为什么不使用volatile,其它线程也能得到当前线程修改后的值,不使用volatile也不存在可见性问题?原来解决可见性问题不一定需要volatile,println也可以的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。