因爲JVM運行程序的實體是線程,而每一個線程建立時JVM都會爲其建立一個工做內存(有些地方稱爲棧空間),工做內存是每一個線程的私有數據區域,而Java內存 模型中規定全部變量都存儲在主內存,主內存是共享內存區域,全部線程均可以訪問,但線程對變量的操做(讀取賦值等)必須在工做內存中進行,首先要將變量從主內存拷貝的本身的工做內存空間,而後對變量進行操做,操做完成後再將變量寫回主內存,不能直接操做主內存中的變量,各個線程中的工做內存中存儲着主內存中的變量副木拷貝,所以不一樣的線程間沒法訪問對方的工做內存,線程間的通訊(傳值)必須經過主內存來完成,其簡要訪問過程以下圖:java
代碼驗證以下:this
import java.util.concurrent.TimeUnit; class MyData{ //定義初始參數,volatile關鍵字使用爲重點 volatile int number = 0; //更改初始參數 public void changeNumber(){ this.number = 60; } } public class VolatileDemo { public static void main(String[] args) { //初始化資源類 MyData myData = new MyData(); new Thread(() -> { System.out.println(Thread.currentThread().getName()+"初始化線程,初始參數爲:"+myData.number); //AAA線程暫停三秒後 try{ TimeUnit.SECONDS.sleep(3); }catch(Exception e){ e.printStackTrace(); } //AAA線程更改初始化參數爲60 myData.changeNumber(); System.out.println(Thread.currentThread().getName()+"線程更改初始化參數爲:"+myData.number); },"AAA").start(); while(myData.number == 0){ //第二個線程是main線程,在number=0時則一直陷入死循環,當number=60時則打印主線程語句。 } System.out.println(Thread.currentThread().getName()+"主線程當前參數:"+myData.number); } }
結果展現:spa
1.初始參數number未加上volatile:線程
2.初始參數number加上volatile:code
總結:blog
volatile是JAVA虛擬機提供的輕量級的同步機制,volatile三大特徵:保證可見性,不保證原子性,禁止指令重排。內存