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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java之volatile如何保证可见性和指令重排序

發布時間:2023/12/4 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java之volatile如何保证可见性和指令重排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 我們先了解CPU緩存

CPU緩存為了解決CPU運算速度與內存讀寫速度不匹配的問題,因為CPU運算速度要比內存讀寫速度快得多

  • 一次主內存的訪問通常在幾十到幾百個時鐘周期
  • 一次L1高速緩存的讀寫只需要1~2個時鐘周期
  • 一次L2高速緩存的讀寫也只需要數十個時鐘周期

CPU大多數情況下讀寫都不會直接訪問內存,取而代之的是CPU緩存,CPU緩存是位于CPU與內存之間的臨時存儲器(簡單理解為寄存器)它容量比內存小得多但是交換速度卻比內存快得多。而緩存中的數據是內存中的一小部分數據,但這一小部分是短時間內CPU即將訪問的,當CPU調用大量數據時,就可先從緩存中讀取,從而加快讀取速度

CPU緩存可分為:一級緩存(是與CPU結合最為緊密的CPU緩存二級緩存三級緩存,每一級緩存中所存儲的數據全部都是下一級緩存中的一部分

CPU要讀取數據時,首先從一級緩存中查找,如果沒有再從二級緩存中查找,如果還是沒有再從三級緩存中或內存中查找。一般來說每級緩存的命中率大概都有80%左右,只剩下20%的總數據量才需要從二級緩存、三級緩存或內存中讀取。

CPU執行計算的過程如下:

  • 程序以及數據被加載到主內存
  • 指令和數據被加載到CPU緩存
  • CPU執行指令,把結果寫到高速緩存
  • 高速緩存中的數據寫回主內存

?

?

?

?

?

?

?

2?總線鎖

每個CPU都有一級緩存,但是,我們卻無法保證每個CPU的一級緩存數據都是一樣的,如何保證各個CPU緩存中的數據是一致的。就是CPU的緩存一致性問題

1)總線鎖

一種處理一致性問題的辦法是使用Bus Locking(總線鎖)。當一個CPU對其緩存中的數據進行操作的時候,往總線中發送一個Lock信號。 這個時候,所有CPU收到這個信號之后就不操作自己緩存中的對應數據了,也就是把數據直接寫入主內存,當操作結束,釋放鎖以后,所有的CPU就去內存中獲取最新數據更新

?

?

?

?

?

?

?

3?volatile如何保證可見性

我們把有volatile修飾的變量編譯成部分匯編,這里有個lock指令

0x01a3de24: lock addl $0X0,(%esp);

如果是寫操作,cpu會發出一個lock指令,CUP會把數據直接寫到到主內存

如果是讀操作,cpu會發出一個unlock指令,?所有的CPU就去內存中獲取最新數據更新

?

?

?

?

?

?

?

4 volatile如何保證指令重排序

現代的操作系統都是多處理器.而每一個處理器都有自己的緩存,并且這些緩存并不是實時都與內存發生信息交換.這樣就可能出現一個cpu上的緩存數據與另一個cpu上的緩存數據不一致的問題.而這樣在多線程開發中,就有可能導致出現一些異常行為.
而操作系統底層為了這些問題,提供了一些內存屏障用以解決這樣的問題.目前有4種屏障.

  • LoadLoad屏障:對于這樣的語句Load1; LoadLoad; Load2,在Load2及后續讀取操作要讀取的數據被訪問前,保證Load1要讀取的數據被讀取完畢。
  • StoreStore屏障:對于這樣的語句Store1; StoreStore; Store2,在Store2及后續寫入操作執行前,保證Store1的寫入操作對其它處理器可見。
  • LoadStore屏障:對于這樣的語句Load1; LoadStore; Store2,在Store2及后續寫入操作被刷出前,保證Load1要讀取的數據被讀取完畢。
  • StoreLoad屏障:對于這樣的語句Store1; StoreLoad; Load2,在Load2及后續所有讀取操作執行前,保證Store1的寫入對所有處理器可見。

在每個volatile寫操作前插入StoreStore屏障,在寫操作后插入StoreLoad屏障;
在每個volatile讀操作前插入LoadLoad屏障,在讀操作后插入LoadStore屏障;
?

由于內存屏障的作用,避免了volatile變量和其它指令重排序?

?

?

?

?

?

參考鏈接:

https://crowhawk.github.io/2018/02/10/volatile/

https://www.jianshu.com/p/ef8de88b1343

https://my.oschina.net/LucasZhu/blog/1537330

?

總結

以上是生活随笔為你收集整理的Java之volatile如何保证可见性和指令重排序的全部內容,希望文章能夠幫你解決所遇到的問題。

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