您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關volatile關鍵字的作用是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
1. 可見性:對一個volatile 變量的讀,總是能看到(任意線程) 對這個 volatile 變量最后的寫入。
2. 原子性:對任意單個 volatile 變量的讀/寫 具有原子性,但類似于 volatile++ 這種復合操作不具有原子性。
內存語義:可以簡單理解為 volatile,sychronize,Atomic,Lock 之類的在 JVM 中的內存方面實現原則。
1、volatile 寫的內存語義如下:
當寫一個 volatile 變量時,JMM(Java 內存模型) 會把該線程對應的本地內存中的共享變量值刷新到主內存
2、volatile 讀的內存語義如下:
當讀到一個 volatile 變量時,JMM會把改線程對應的本地內存職位無效。線程接下來將從只內存中讀取共享變量
如果我們將flag變量以volatile關鍵字修飾,那么實際上:線程A在寫flag變量后,本地內存A中被線程A更新過的兩個共享變量的值都被刷新到主內存中。
在讀flag變量后,本地內存B包含的值已經被置為無效。此時,線程B必須從主內存中讀取共享變量。線程B的讀取操作將導致本地內存B與主內存中的共享變量的值變成一致。
如果我們把volatile寫和volatile讀兩個步驟綜合起來看的話,在讀線程B讀一個volatile變量后,寫線程A在寫這個volatile變量之前所有可見的共享變量的值都將立即變得對讀線程B可見。
4、volatile 內存語義的實現
總結起來就是:
當第二個操作是volatile寫時,不管第一個操作是什么,都不能重排序。這個規則確保volatile寫之前的操作不會被編譯器重排序到volatile寫之后。
當第一個操作是volatile讀時,不管第二個操作是什么,都不能重排序。這個規則確保volatile讀之后的操作不會被編譯器重排序到volatile讀之前。
當第一個操作是volatile寫,第二個操作是volatile讀時,不能重排序。
在Java中對于 volatile 修飾的變量,編譯器在生成字節碼時,會在指令序列中插入內存屏障來禁止特定類型的處理器重排序問題
什么是內存屏障{
Java編譯器在生成指令序列的適當位置會插入內存屏障指令來禁止特定類型的處理器重排序,從而讓程序按我們預想的流程去執行。
1、保證特定操作的執行順序。
2、影響某些數據(或則是某條指令的執行結果)的內存可見性。}
storestore屏障:對于這樣的語句store1; storestore; store2,在store2及后續寫入操作執行前,保證store1的寫入操作對其它處理器可見。(也就是說如果出現storestore屏障,那么store1指令一定會在store2之前執行,CPU不會store1與store2進行重排序)
storeload屏障:對于這樣的語句store1; storeload; load2,在load2及后續所有讀取操作執行前,保證store1的寫入對所有處理器可見。(也就是說如果出現storeload屏障,那么store1指令一定會在load2之前執行,CPU不會對store1與load2進行重排序)
在每個volatile讀操作的后面插入一個LoadLoad屏障。在每個volatile讀操作的后面插入一個loadstore屏障。
loadload屏障:對于這樣的語句load1; loadload; load2,在load2及后續讀取操作要讀取的數據被訪問前,保證load1要讀取的數據被讀取完畢。(也就是說,如果出現loadload屏障,那么load1指令一定會在load2之前執行,CPU不會對load1與load2進行重排序)
loadstore屏障:對于這樣的語句load1; loadstore; store2,在store2及后續寫入操作被刷出前,保證load1要讀取的數據被讀取完畢。(也就是說,如果出現loadstore屏障,那么load1指令一定會在store2之前執行,CPU不會對load1與store2進行重排序)
通過對 OPEN JDK 中的 unsafe.cpp 源碼的分析,會發現被 volatile關鍵字修飾的變量會存在一個 “lock:” 的前綴。
Lock 前綴,Lock不是一種內存屏障,但是它能完成類似于內存屏障的功能。Lock 會對CPU 總線和高速緩存加鎖,可以理解為 CPU 指令集的一種鎖。
同時該指令會將當前處理器緩存行的數據直接寫到系統內存中,且這個寫回內存的操作會是在其他 CPU 里緩存了該地址的數據無效。
再具體的執行上,他先對總線和緩存加鎖,然后執行后面的指令,最后釋放鎖會吧高速緩存中的臟數據全部刷新回主內存。在 Lock 鎖住總線的時候,其他 CPU 的讀寫請求會被阻塞,知道鎖釋放
看完上述內容,你們對volatile關鍵字的作用是什么有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。