volatile僅僅用來保證該變量對所有線程的可見性,但不保證原子性
volatile與synchronized的差異
volatile | synchronized |
---|---|
告訴jvm當前變量在寄存器中的值是不確定的,需要從主存中讀取 | 鎖定當前變量,只有當前線程可以訪問該變量,其他線程被阻塞 |
變量級別 | 變量、方法級別 |
變量修改可見性 | 變量修改可見性和原子性 |
不會造成線程阻塞 | 可能會造成阻塞 |
標記變量不會被編譯器優化 | 編輯變量會被編輯器優化 |
僅在有限情況下volatile 可以替代鎖,要使volatile變量提供理想的線程安全,必須同時滿足下面兩個條件:
- 對變量的寫操作不依賴與當前值
- 改變量沒有包含在具有其他變量的不變式中
volatile適用情況
- boolean 狀態標志
- 一次性安全發布,volatile 類型的引用可以確保對象的發布形式的可見性,但是如果對象的狀態在發布后將發生更改,那么就需要額外的同步。
- 獨立觀察,發布的值是有效不可變的
- volatile bean 模式。
-- volatile bean 模式的基本原理是:很多框架為易變數據的持有者(例如 HttpSession)提供了容器,但是放入這些容器中的對象必須是線程安全的。
5.開銷較低的讀-寫鎖策略
并發編程中的三個概念
1.原子性 --java內存模型只保證基本讀取和復制時原子性操作,除此外需要通過synchronized和lock來實現
2.可見性 --使用volatile修飾共享變量,保證被修飾的變量會被立即更新到主存,其他線程需要讀取時,會從內存中讀取新值。或通過synchronized和lock也可保證
3.有序性 --可以通過volatile或synchronized或lock來保證