我們來看一下jmm是如何解釋的
jmm規定了所有的變數都儲存在主記憶體(main memory)中,多個執行緒共享主記憶體中
的資料。每個執行緒都有自己的工作記憶體(working memory),執行緒的工作記憶體中保
存了該執行緒使用到的變數在主記憶體的副本拷貝,執行緒對變數的所有操作(讀取、賦
值等)都必須在工作記憶體中進行,而不能直接讀寫主記憶體中的變數。不同的執行緒之
間也無法直接訪問對方工作記憶體中的變數,執行緒之間值的傳遞都需要通過主記憶體來
完成。
我們先來看一下volatile的可見性可見性:在多執行緒情況下,當乙個執行緒將主記憶體中的資料拷貝到工作記憶體中,在自
己的工作記憶體中對資料進行修改,修改之後將工作記憶體中的資料重新整理到主記憶體中,
因為主記憶體中的資料發生的變化,這時會通知其他的執行緒來重新獲取當前共享資料
。通俗來講:乙個執行緒對資料進行修改,其他的執行緒可見。
我們再來談一談volatile為什麼不能保證原子性?我們構造出乙個例子:
工作記憶體中有乙個共享的變數 int number =
0 我們有四個執行緒:執行緒1、執行緒2、執行緒3、執行緒4
假設執行緒中的操作都是對 number++
我們做出假設:
開始四個執行緒都將共享變數讀入到自己的工作記憶體中,同時執行++操作,然後
執行緒1將自己的變數重新整理到主記憶體中,此時值為 number =
1,因為變數發生的變化
,執行緒2、執行緒3都開始重新讀取資料進行操作,執行緒4在沒有收到變數發生改變的
通知之前,已經將自己的變數重新整理到主記憶體,此時主記憶體中的變數 number 還是等
於1,但此時執行緒1、執行緒4都已經執行完,所以最後的結果時2或者3.
為什麼volatile不能保證原子性
原子操作簡單來說,原子操作 atomic 就是不可分割的操作,在計算機中,就是指不會因為新城排程被打斷的操作。比如,簡單的賦值就是乙個原子操作 m 6 這是個原子操作假如m原先的值為0,那麼對於這個操作,要麼執行成功m程式設計了6,要麼沒執行m還是0,而不會出現諸如m 3,這種中間狀態。但是宣告並賦...
volatile為什麼不能保證變數原子性
看個例子,僅是個人理解。public class volatiledemo 當進行自增操作,位元組碼是這樣的 1 獲取變數的值併入棧 2 把1入棧 3 依次取出棧中兩個運算元相加併入棧 假設為臨時變數t 4 取出棧頂值賦值給變數 而volatile的可見性指的是第4步,當修改變數後,把新值重新整理到...
volatile不能保證原子性
在討論原子性操作時,我們經常會聽到乙個說法 任意單個volatile變數的讀寫具有原子性,但是volatile 這種操作除外。所以問題就是 為什麼volatile 不是原子性的?因為它實際上是三個操作組成的乙個符合操作。首先獲取volatile變數的值 將該變數的值加1 將該volatile變數的值...