volatile 也是多線程的解決方案之一。**volatile 可以保證可見性,可是不能保證原子性。**它只能做用於變量,不能做用於方法。當一個變量被聲明爲 volatile 的時候,任何對該變量的讀寫都會繞太高速緩存,直接讀取主內存的變量的值。緩存
如何理解直接讀寫主內存的值:回到 多線程生成的緣由(Java內存模型與i++操做解析) ,在 i++ 操做的時候,當 進行 執行引擎 對 變量 進行 + 1 以後,原來 是應該寫入到 本地內存中,再由本地內存寫入到主內存中,可是 因爲 變量使用了 volatile 的修飾,因此 該值不會通過本地內存,而是直接寫入到 主內存中去。 讀取也是一樣的道理。多線程
使用volatile 有兩點須要注意的地方:線程
public class Test { public static volatile int i = 0; public static void main(String args[]){ new Thread(new Runnable(){ public void run(){ for(int j = 0; j < 10000; j++) i++; System.out.println("Thread1 end..."); } }).start(); new Thread(new Runnable(){ public void run(){ for(int j = 0; j < 10000; j++) i++; System.out.println("Thread2 end..."); } }).start(); i++; try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("i = " + i); } }
private Date start; private Date end; public void setInterval(Date newStart, Date newEnd) { // 檢查start<end是否成立, 在給start賦值以前不變式是有效的 start = newStart; // 可是若是另外的線程在給start賦值以後給end賦值以前時檢查start<end, 該不變式是無效的 end = newEnd; // 給end賦值以後start<end不變式從新變爲有效 }
最後,關於何時使用 volatile,通常是用來當作標記來使用。好比說,當shutdown() 方法被調用的時候,全部的 doWork() 方法都會停下來。code