volatile能保證原子性嗎?

2021-10-04 07:42:16 字數 937 閱讀 4844

volatile不能保證原子性。

當跟自增操作一起時,自增操作本身不是原子性操作。

class

data

}public

class

main}}

, string.

valueof

(i))

.start()

;}while

(thread.

activecount()

>=2)

system.out.

println

(data.number);}

}

number輸出不是20000。

這裡面就有乙個誤區了,volatile關鍵字能保證可見性沒有錯,但是上面的程式錯在沒能保證原子性。可見性只能保證每次讀取的是最新的值,但是volatile沒辦法保證對變數的操作的原子性。

在前面已經提到過,自增操作是不具備原子性的,它包括讀取變數的原始值、進行加1操作、寫入工作記憶體。那麼就是說自增操作的三個子操作可能會分割開執行,就有可能導致下面這種情況出現:

假如某個時刻變數inc的值為10,

執行緒1對變數進行自增操作,執行緒1先讀取了變數inc的原始值,然後執行緒1被阻塞了;

然後執行緒2對變數進行自增操作,執行緒2也去讀取變數inc的原始值,由於執行緒1只是對變數inc進行讀取操作,而沒有對變數進行修改操作,所以不會導致執行緒2的工作記憶體中快取變數inc的快取行無效,所以執行緒2會直接去主存讀取inc的值,發現inc的值時10,然後進行加1操作,並把11寫入工作記憶體,最後寫入主存。

那麼兩個執行緒分別進行了一次自增操作後,inc只增加了1。會出現寫回主記憶體覆蓋問題。

根源就在這裡,自增操作不是原子性操作,而且volatile也無法保證對變數的任何操作都是原子性的。

volatile不能保證原子性

在討論原子性操作時,我們經常會聽到乙個說法 任意單個volatile變數的讀寫具有原子性,但是volatile 這種操作除外。所以問題就是 為什麼volatile 不是原子性的?因為它實際上是三個操作組成的乙個符合操作。首先獲取volatile變數的值 將該變數的值加1 將該volatile變數的值...

volatile不保證原子性

1.什麼是原子性?不可分割 完整性,即某個執行緒正在做某個具體業務時,中間不可以被加塞或者被分割,需要整體完整,要麼同時成功,要麼同時失敗 2.寫乙個demo來驗證volatile不保證原子性 大概率結果不是2000 因為i 不是一步操作,而不是一步操作,所以無法保證原子性 class source...

為什麼volatile不能保證原子性

原子操作簡單來說,原子操作 atomic 就是不可分割的操作,在計算機中,就是指不會因為新城排程被打斷的操作。比如,簡單的賦值就是乙個原子操作 m 6 這是個原子操作假如m原先的值為0,那麼對於這個操作,要麼執行成功m程式設計了6,要麼沒執行m還是0,而不會出現諸如m 3,這種中間狀態。但是宣告並賦...