知識社群登入
位置: 艾鍗學院 Blog > 專業論壇 > 討論
[Android實作問題] what is a " volatile " ?
1樓
Hello Jarey,

當我一個成員方法或變數宣告一個  " volatile " 這個關鍵字是代表什麼意思呢? 可否清楚的說明呢

Thank you 
小K
2樓
這是一個比較深入的問題,相信你應該也有去google到許多的資料,但要能真正了解其中函義

你必須先深入了解Java 記憶體模型 與 Java Thread資料同步化...等相關技術領域。


Volatile的定義說明如下:
volatile 是在告知處理器, 不要將變數copy到work memory中操作, 而是直接在Main memory上操作.
不過我想我單純提供定義說明,還是很難讓人理解這到底有什麼用處與差別。 所以我們必須先從
Java Memory Model(記憶體模型)看起。

Java Memory Model:

在多執行緒的情況下,每個Thread都會有一塊自己的work memory,thread是被允許能夠在work memory中
暫存 main memory變數的質。在多執行緒的情況下,相有多個Thread同時會對同一個main memory的變數
做存取時,就有可能發生race condition的情形,某個thread在對變數寫入資料時,其它thread的work memory
中暫存的資料並不會同時被進行更新變更,這就會有資料不同步的問題。 

Java Memory Model


Java Thread資料不一致問題:

我寫一個很簡單的例子來說明: 

在這個列子中stop變數會在run之中的每次迴圈中被讀取,同時

也會被其它Thread透過呼叫setStop函式,來對stop變數做寫入動作,然而因為

thread會將變數自main memory取出到 work memory暫存的風險,因此有可能

在迴圈中的stop己被載入到該thread的work memory而沒去查覺到有另一個thread

對stop變數進行變動.  因此加上volatile可以避免這種風險發生.

public class WorkThread extends Thread {

private volatile boolean stop;

public void run() {
while (!stop) {
// 執行thread工作.....
}
}

public void setStop(boolean isStop) {
stop = isStop;
}
}

Volatile關鍵字:

總結,volatile關鍵字可以視為強迫JVM 不要暫時copy變數到work thread memory之中,而是直接從main 

memory中存讀取,然而這與VM實作機制有關,在jdk 1.2之前Java Memory Model對Volatile變數的都

是會從Main Memory中讀取,但隨著JDK5.6,7 不斷的改版,VM的實作變的更複雜且有更多新的記憶體模型

與最佳化機制,另外還有許多非官方版的JVM,以各種不同的VM實作機制來說,開發者不能假設變數都會從

main memory中讀取。

同時volatile是只能以atomic方式操作的變數上運作(例如 ++ , --就不是atomic)並且在使用上除非你相當了

解Thread與Memory模型的運作機制,不同是很容易設計錯誤,只能算是一個比較輕量級的同步機制,它能

以少量的程式碼去實現synchronized 的一小部份功能.
3樓
Thanks for Jarey