前言
被volatile修飾的變量能夠保證每個線程能夠獲取該變量的最新值百炬,從而避免出現(xiàn)數(shù)據(jù)臟讀的現(xiàn)象褐隆。
相信很多人都用過volatile這個關(guān)鍵字,也知道它的妙用剖踊,但是其底層原理是否知曉呢庶弃?通過這篇文章就一目了然了。 在了解volatile之前CPU多及緩存架構(gòu)和JMM內(nèi)存模型德澈,如果不了解的在我的其他文章里面有講到這兩點歇攻。
通過use方法使用本線程工作內(nèi)存中變量flag=true(線程1進(jìn)入死循環(huán)狀態(tài)箍镜,知道flag變成了false)
線程2調(diào)用unlock方法诈悍,對鎖定的緩存行進(jìn)行解鎖祸轮,解鎖完成之后其他線程從主內(nèi)存重新獲取變量flag=false。
volatile能保證原始數(shù)據(jù)類型賦值的原子性,無法保證復(fù)合操作的原子性给猾。
線程的運(yùn)行有隨機(jī)性,假設(shè)此時線程1池颈、2尾序、3都從主內(nèi)存讀取變量i=0到了各自線程的工作內(nèi)存
線程1、2饶辙、3都開始通過assign對本地變量進(jìn)行賦值操作蹲诀,此時各自線程內(nèi)都變量i的值都變成了1
當(dāng)x淫半、y通過volatile進(jìn)行修飾時
volatile重排序規(guī)則表(針對編譯器重排序):
上面的例子符合第二個volatile寫第一個普通寫規(guī)則,編譯器不會進(jìn)行重排序猴鲫。
需要注意的是:volatile寫是在前面和后面分別插入內(nèi)存屏障豁陆,而volatile讀操作是在后面插入兩個內(nèi)存屏障
StoreStore屏障:禁止上面的普通寫和下面的volatile寫重排序;
StoreLoad屏障:防止上面的volatile寫與下面可能有的volatile讀/寫重排序
LoadLoad屏障:禁止下面所有的普通讀操作和上面的volatile讀重排序