1. 程式人生 > >淺談volatile在i++情況下失效

淺談volatile在i++情況下失效

概述

如果你對volatile不陌生的話,應該會知道volatile能夠保證共享變數對執行緒的可見性。
那為什麼volatile無法保證 i++ 操作的執行緒可見性呢?

分析

假設i的初始值為0,現有兩個執行緒,分別為執行緒1和執行緒2進行 i++ 操作,我們來分析一下為什麼會出現錯誤。

首先,i++並不是原子操作,我們可以將這個操作拆分為3個步驟。

  1. 執行緒從主記憶體把遍歷載入到快取。
  2. 執行緒執行i++操作。
  3. 執行緒將i的新值重新整理到主記憶體。

那麼進行如下過程,則會發生執行緒安全問題。

  1. 執行緒1將變數載入到快取。但是還沒有執行 i++ 操作。
  2. 執行緒2將變數載入到快取,然後執行i++操作。
  3. 由於執行緒2快取變數已經發生了變化,使得執行緒1的快取行無效。
  4. 按我們以前的理解,由於執行緒1快取行無效,那執行緒1應該主動去主記憶體load最新的值。而實際上並不是這樣的,volatile的作用並不是在變數改變的時候,讓其他執行緒重新載入主記憶體的變數值,而是置其他執行緒快取內的變數值無效。也就是說,此時執行緒1並不會重新去從主記憶體載入i的值,而是繼續進行i++操作,導致資料錯誤。