---
# System prepended metadata

title: Volatile
tags: [Thread, Java]

---

# Volatile
###### tags: `Java` `Thread`
**Volatile**

使用限制
只能修飾類變量
方法參數、常量、區域變數皆不可使用

語意
 1. 保證不同線程之間操作相同數據時的可見性
 2. 禁止對指令重排序

實現原理
被volatile修飾的變量會存在一個"lock;"的前綴
而這個前綴相當於一個內存屏障並且為指令的執行提供了以下保障

 1. 確保指令重排序不會將其後面的代碼排到內存屏障之前
 2. 確保指令重排序不會將其前面的代碼排到內存屏障之後
 3. 確保執行到內存屏障修飾的指令前實前面指令全部執行完成
 4. 強制將工作內存中值的修改刷新至主內存
 5. 如果是寫操作會導致其他線程工作內存中的cache資料失效

注意 : 此修飾字不保證被修飾的變量會具有原子性

volatile 與 synchronized 差異
1.使用上差異
	volatile:只能修飾靜態變量或類變量
	synchronized:只能修飾方法或block
2.原子性
	volatile:不具備原子性
	synchronized:是一種排他機制，因此被修飾的區塊是無法被中斷的，因此能保證原子性
3.可見性
	兩者皆保證共享資源再多線程間的可見性但實現機制完全不同
	volatile:機器指令
	synchronized:JVM指令
4.有序性
	volatile:關鍵字禁止JVM及CPU對其重排序，所以保證有序性
	synchronized:被修飾的區塊內會進行指令重排序但保證結果不變，因此保證 有序性
5.其他
	volatile:不會阻塞線程
	synchronized:會阻塞線程