volatile 淺顯描述

volatile 並不能保證併發下 操作的原子性,而是保證了併發時的可見性。


僅在以下場景中可以保證操作的原子性

1 運算的結果不依賴於當前的變量值,或者只有單一線程在修改變量

2 變量不需要其他變量共同參與不變約束


需要的背景知識:

1 java多線程的內存獲取

java對於內存的操作是間接的,每一條線程都有一個工作內存,這些工作內存與主內存之間還要進行 save 和 load操作 才能將數據 存儲進內存 或者 加載進工作內存。
而普通變量與 volatile變量的區別就是  volatile變量可以保證更新過的數據可以優先刷新進內存,並且立即被工作內存獲取到。

2 如何立即獲取到

用volatile修飾的變量在更新數值操作的時候,底層的編譯後字節碼 會在把寫入操作 用內存屏障擴起來,方法就是lock關鍵字。而這樣做的話,在這句賦值操作執行完成之後,其他同時訪問的cpu會進行一次內核無效化——相當於重新執行一次store 和write的操作。

3 爲什麼需要內存屏障

因爲編譯的時候,各條指令需要被重新打亂排序,可以允許cpu不按程序規定的順序將指令發送到各個電路單元去處理,加入內存屏障之後,保證了cpu 只能在執行完這條寫入操作之後,再去執行其他操作。
指令重排序也不是隨機重排序的,也遵循着一定的規則:
控制流次序規則
管程鎖定規則,就是一個鎖的 釋放 必須發生在下一次的 lock之前
volatile變量規則,對於同一個變量的寫操作發生在讀操作之前
線程啓動、終止、中斷規則
對象終結規則
傳遞性,就是 a先於b   b先於c  a就要先於c

4 爲什麼會重排序

cpu做的優化。。不是死鎖方面的 就是效率方面的   所以重排序主要是優化了效率,一個元件被分配了任務  另一個元件空着 cpu就很不爽,就像流水線分發任務一樣,同一時間點  或者說 在單位時間內,併發的元件數量提升了,整體的效率也就提升了,cpu爽了,電腦爽了,你也爽了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章