1. 程式人生 > >多線程之volatile關鍵字(五)

多線程之volatile關鍵字(五)

ips 變量 tope 每次 stop ++ .com 訪問 不相信

開始全文之前,先鋪墊一下jvm基礎知識以及線程棧:

JVM棧是線程私有的,每個線程創建的同時都會創建JVM棧,JVM棧中存放的為當前線程中局部基本類型的變量(java中定義的八種基本類型:boolean、char、byte、short、int、long、float、double)、部分的返回結果以及Stack Frame,非基本類型的對象在JVM棧上僅存放一個指向堆上的地址。

接下來說說volatile:

用volatile修飾的變量,線程在每次使用變量的時候,都會讀取變量修改後的最的值。volatile很容易被誤用,用來進行原子性操作。如果要深入了解volatile關鍵字的作用,就必須先來了解一下JVM在運行時候的內存分配過程。在 java 垃圾回收整理一文中,描述了jvm運行時刻內存的分配。其中有一個內存區域是jvm虛擬機棧,每一個線程運行時都有一個線程棧,線程棧保存了線程運行時候變量值信息。當線程訪問某一個對象時候值的時候,首先通過對象的引用找到對應在堆內存的變量的值,然後把堆內存變量的具體值load到線程本地內存中,建立一個變量副本,之後線程就不再和對象在堆內存變量值有任何關系,而是直接修改副本變量的值,在修改完之後的某一個時刻(線程退出之前),自動把線程變量副本的值回寫到對象在堆中變量。這樣在堆中的對象的值就產生變化了。下面一幅圖描述這寫交互!

有了以上知識做鋪墊,接下來直接上代碼:
public class VolatileTest extends Thread {
    
    volatile boolean flag = false;
    int i = 0;
    
    public void run() {
        while (!flag) {
            i++;
        }
    }
    
    public static void main(String[] args) throws Exception {
        VolatileTest vt = new VolatileTest();
        vt.start();
        Thread.sleep(2000);
        vt.flag = true;
        System.out.println("stope" + vt.i);
    }
}

如果你不相信,可以把變量falg前面的volatile去掉,執行完以後,你可以看看你的myeclipse或者eclipse裏面的服務配置,是否仍舊在啟用狀態:去掉volatile以後如下圖,表示線程仍舊執行狀態: 本文部分內容摘自:http://www.cnblogs.com/daxin/p/3364014.html#undefined

多線程之volatile關鍵字(五)