1、volatitle是java的一種輕量級的并發機制
2、被volatitle修飾的關鍵字也存在并發問題
3、一般的變量在使用時需要把變量從主內存控件加載到工作內存空間(可以映射為堆內存和棧內存模型),工作內存空間是線程私有,然后使用外之后才能更新到主內存,這期間的操作不是原子操作,所以在高并發下,存在存儲不一致問題。
4、volatitle關鍵字修飾的變量能夠保證每次在工作空間使用內存時從主內存刷新變量的值,改變之后跟新到主內存,但是在使用的時候并不能保證是原子操作,在更新內存的之前,可能其他線程已經改變了變量 的值了,所以還是存在并發問題。只是比普通的變量“更可靠”罷了。
5、所以volatitle關鍵字只能保證可見性。我們仍然需要加synchronize或者concurrent包里面的類來保證原子性。
在不符合下面兩條規則的場景中,仍需要枷鎖:
1、運算結果并不依賴變量當前的值,或者保證只有單一線程修改變量的值
2、變量不需要與其他狀態變量共同參與不變約束。
比如下列場景就是好volatitle關鍵字:
volatitle boolean isRun;
public void changeState() {
isRun = fasle;
}
public void run() {
while(isRun ) ....
}
當changeState方法執行的時候,其他線程的run方法立即停止執行。
使用volatitle的第二個語義是禁止指令重排(指令重排:多條指令交給cpu執行的時候,可以進行優化,不按順序交給多條電路執行),指令重排會造成同一段代碼多次執行的順序不一定相等。
- 原子性、可見性、有序性
有序性:在線程內部觀察都是有序的,在一個線程觀察另一個線程都是無序的。前半句是指線程串行語義,后半句是指指重排現象和工作內存與主內存同步現象。