关于 Volatile
实际的意义,简单来说,用volatile确定义的一个变量与普通变量不同之处在于,在多线程的环境下,每个独立的线程都有自己的一块内存空间,为了提高 速度,JAVA的线程会把共有的变量映射到自己的内存空间(共有的变量就是可以为多个线程访问的变量),产生一个copy。
比如,一个线程改变了共有变量,其实它仅仅改变了那个自己的copy。共有变量其实没有真正的改变。所以,其它的线程并没有觉察到共有变量的改变,JVM会在某个不确定的时候,才会去更改共有变量的实体。
如果,你用volatile 声明这个共有变量,它就会强制改变它的线程直接去改变它的实体,并且强制读取的线程直接读取实体的值,而每个线程不会产生这个变量的拷贝。
主要用途:
用来声明多线程环境下的状态敏感的变量。
再给你一个例子:
Listing 7.1 Volatile.java—Demonstration Showing How volatile Makes a Difference
1: public class Volatile extends Object implements Runnable {
2: // not marked as ‘volatile’, but it should be!
3: private int value;
4:
5: private volatile boolean missedIt;
6:
7: // doesn’t need to be volatile-doesn’t change
8: private long creationTime;
9:
10: public Volatile() {
11: value = 10;
12: missedIt = false;
13: creationTime = System.currentTimeMillis();
14: }
15:
16: public void run() {
17: print(“entering run()”);
18:
19: // each time, check to see if ‘value’ is different
20: while ( value < 20 ) {
21:
22: // Used to break out of the loop if change to
23: // value is missed.
24: if ( missedIt ) {
25: int currValue = value;
26:
27: // Simply execute a
synchronized statement on an
28: // arbitrary object to see the effect.
29: Object lock = new Object();
30: synchronized ( lock ) {
31: // do nothing!
32: }
33:
34: int valueAfterSync = value;
35:
36: print(“in run() - see
value=” + currValue +
37:
“, but rumor has it that
it changed!”);
38: print(“in run() - valueAfterSync=” +
39: valueAfterSync);
40:
41: break;
42: }
43: }
44:
45: print(“leaving run()”);
46: }
47:
48: public void workMethod() throws InterruptedException {
49: print(“entering workMethod()”);
50:
51: print(“in workMethod() - about to sleep for 2 seconds”);
52: Thread.sleep(2000);
53:
54: value = 50;
55: print(“in workMethod() - just set value=” + value);
56:
57: print(“in workMethod() - about to sleep for 5 seconds”);
58: Thread.sleep(5000);
59:
60: missedIt = true;
61: print(“in workMethod() - just set missedIt=” + missedIt);
62:
63: print(“in workMethod() - about to sleep for 3 seconds”);
64: Thread.sleep(3000);
65:
66: print(“leaving workMethod()”);
67: }
68:
69: private void print(String msg) {
70: // This method could have been simplified by using
71: // functionality present in the java.text package,
72: // but did not take advantage of it since that package
73: // is not present in JDK1.0.
74:
75: long interval = System.currentTimeMillis() -
76: creationTime;
77:
78: String tmpStr = “ “ + (
interval / 1000.0 ) + “000”;
79:
80: int pos = tmpStr.indexOf(“.”);
81: String secStr = tmpStr.substring(pos - 2, pos + 4);
82:
83: String nameStr = “ “ +
84: Thread.currentThread().getName();
85:
86: nameStr = nameStr.substring(nameStr.length() - 8,
87:
nameStr.length());
88:
89: System.out.println(secStr + “ “ + nameStr + “: “ + msg);
90: }
91:
92: public static void main(String[] args) {
93: try {
94: Volatile vol = new Volatile();
95:
96: // slight pause to let some time elapse
97: Thread.sleep(100);
98:
99: Thread t = new Thread(vol);
100: t.start();
101:
102: // slight pause to allow run() to go first
103: Thread.sleep(100);
104:
105: vol.workMethod();
106: } catch ( InterruptedException x ) {
107: System.err.println(
108: “one of the sleeps was interrupted”);
109: }
110: }
111: }