併發程式設計 volatile底層實現原理

2021-09-25 18:22:27 字數 1451 閱讀 3967

解決可見性使用快取一致性。

防止指令重排序使用記憶體屏障,保證有序性。

有volatile變數修飾的共享變數,編譯時會有lock字首。

·lock字首指令會引起處理器快取回寫到記憶體。(匯流排鎖、快取鎖)

·乙個處理器的快取回寫到記憶體會導致其他處理器的快取無效。(mesi、嗅探)

處理器上有一套完整的協議,來保證 cache 的一致性,比較經典的應該就是mesi 協議了,它的方法是在 cpu 快取中儲存乙個標記位,這個標記為有四種

狀態ø m(modified) 修改快取,當前 cpu 快取已經被修改,表示已經和記憶體中的 資料不一致了

ø i(invalid) 失效快取,說明 cpu 的快取已經不能使用了

ø e(exclusive) 獨佔快取,當前cpu的快取和記憶體中資料保持一直,而且其他 處理器沒有快取該資料

ø s(shared) 共享快取,資料和記憶體中資料一致,並且該資料存在多個 cpu快取中

每個 core 的 cache 控制器不僅知道自己的讀寫操作,也監聽其它 cache 的讀 寫操作,嗅探(snooping)"協議

cpu 的讀取會遵循幾個原則:

如果快取的狀態是 i,那麼就從記憶體中讀取,否則直接從快取讀取

如果快取處於 m 或者 e 的 cpu 嗅探到其他 cpu 有讀的操作,就把自己的緩 存寫入到記憶體,並把自己的狀態設定為 s

做技術人的指路明燈,做職場生涯的精神導師

只有快取狀態是m或e的時候,cpu才可以修改快取中的資料,修改後,緩 存狀態變為 mc

對於宣告了volatile的變數進行寫操作,jvm就會向處理器傳送一條lock字首的指令,把這個變數所在的快取行的數 據寫回到系統記憶體,再根據我們前面提到過的mesi的快取一致性協議,來保證多cpu下的各個快取記憶體中的資料的 一致性。

在多核心多執行緒下的指令重排序會影響可見性問題。

使用記憶體屏障解決

前提是編譯器的優化亂序和cpu的執行亂序。

cpu層面的記憶體屏障

寫屏障(store barrier)

、讀屏障

(load barrier)

和全屏障

(full barrier)

,主要的作用是 ø

防止指令之間的重排序 ø

保證資料的可見性

編譯器層面的

loadload barriers

storestore barriers

loadstore barries

storeload barries

追加64位元組提高併發程式設計的效率。

併發程式設計 volatile

併發程式設計中的三個概念 原子性即乙個操作或者多個操作 要麼全部執行並且執行的過程不會被任何因素打斷,要麼就都不執行 可見性指當多個執行緒訪問同乙個變數時,乙個執行緒修改了這個變數的值,其他執行緒能夠立即看得到修改的值 有序性即程式執行的順序按照 的先後順序執行 jvm在真正執行這段 的時候會保證語...

併發程式設計(3)volatile

原子性,可見性,有序性。只要有乙個不能保證,就有可能導致程式的執行錯誤 synchronized就能保障原子性,可見性,有序性,1.因為synchronized能保障任意乙個時刻只有乙個執行緒執行該 塊,自然就不存在原子性的問題 2.在釋放鎖之前會將變數的修改重新整理到主存中,因此保證可見性 3.又...

volatile底層詳解

執行緒執行時把資料放到棧中 1 啟動執行緒時,位元組碼執行引擎需要往棧裡面新增資料,而這些操作是需要通過cpu來完成的,2 位元組碼執行引擎會把位元組碼交給解釋執行器或者jit優化 兩種方式 翻譯成彙編指令,彙編指令通過硬體翻譯成二進位制,也就是cpu能執行的二進位制語言 位元組碼翻譯成彙編指令較慢...