我們知道,在Java中設置變量值的操作,除了long和double類型的變量外都是原子操作,也就是說,對于變量值的簡單讀寫操作沒有必要進行同步。這在JVM 1.2之前,Java的內存模型實現總是從主存讀取變量,是不需要進行特別的注意的。而隨著JVM的成熟和優化,現在在多線程環境下volatile關鍵字的使用變得非常重要。在當前的Java內存模型下,線程可以把變量保存在本地內存(比如機器的寄存器)中,而不是直接在主存中進行讀寫。這就可能造成一個線程在主存中修改了一個變量的值,而另外一個線程還繼續使用它在寄存器中的變量值的拷貝,造成數據的不一致。把變量聲明為volatile(不穩定的),這就指示JVM,這個變量是不穩定的,每次使用它都到主存中進行讀取。一般說來,多任務環境下各任務間共享的標志都應該加volatile修飾。
在一些情況下,使用volatile可以達到同步的目的,在某種程度上相當于synchronized關鍵字;為什么說是一定程度上呢,這就要從synchronized同步關鍵字說起了,synchronized在Java語言中可以實現兩個功能,互斥性和可見性。互斥性是指任意時刻只能有一個線程持有特定的鎖,從而可以實現對共享數據的協調訪問;而可見性說的是,任意線程修改的共享數據對于其他線程必須是可見的,也就是說不允許其他線程拿到舊的數據。而volatile關鍵字只能實現可見性,也就是說用volatile修飾的變量的修改對于其他線程是可見的,如果該值被修改,其他線程可以立即得到新值。下面的代碼簡單展示了volatile的一個簡單應用,線程的退出:
在一些情況下,使用volatile可以達到同步的目的,在某種程度上相當于synchronized關鍵字;為什么說是一定程度上呢,這就要從synchronized同步關鍵字說起了,synchronized在Java語言中可以實現兩個功能,互斥性和可見性。互斥性是指任意時刻只能有一個線程持有特定的鎖,從而可以實現對共享數據的協調訪問;而可見性說的是,任意線程修改的共享數據對于其他線程必須是可見的,也就是說不允許其他線程拿到舊的數據。而volatile關鍵字只能實現可見性,也就是說用volatile修飾的變量的修改對于其他線程是可見的,如果該值被修改,其他線程可以立即得到新值。下面的代碼簡單展示了volatile的一個簡單應用,線程的退出:
1
public class Monitor implements Runnable {
2
3
private volatile Thread blinker;
4
boolean isRunning = false;
5
6
7
@Override
8
public void run() {
9
10
Thread thisThread = Thread.currentThread();
11
while (blinker == thisThread) {
12
try {
13
thisThread.sleep(50);
14
} catch (InterruptedException e) {
15
}
16
//To do you task
17
}
18
19
}
20
21
22
public void startMonitor() {
23
blinker = new Thread(this);
24
blinker.start();
25
}
26
27
public void stopMonitor() {
28
blinker = null;
29
}
30
31
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31
