多線程之volatile關鍵字(五)
阿新 • • 發佈:2017-05-24
ips 變量 tope 每次 stop ++ .com 訪問 不相信 開始全文之前,先鋪墊一下jvm基礎知識以及線程棧:
有了以上知識做鋪墊,接下來直接上代碼:
如果你不相信,可以把變量falg前面的volatile去掉,執行完以後,你可以看看你的myeclipse或者eclipse裏面的服務配置,是否仍舊在啟用狀態:去掉volatile以後如下圖,表示線程仍舊執行狀態: 本文部分內容摘自:http://www.cnblogs.com/daxin/p/3364014.html#undefined
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關鍵字(五)