簡要概述java記憶體模型,以及volatile關鍵字,javavolatile

來源:互聯網
上載者:User

簡要概述java記憶體模型,以及volatile關鍵字,javavolatile

 如果我們要想深入瞭解Java並發編程,就要先理解好Java記憶體模型。Java記憶體模型定義了多線程之間共用變數的可見度以及如何在需要的時候對共用變數進行同步。原始的Java記憶體模型效率並不是很理想,因此Java1.5版本對其進行了重構,現在的Java8仍沿用了Java1.5的版本。

  在java中每個線程都有一塊本地記憶體,而本地記憶體存放的變數是主記憶體的副本。相當於線上程啟動時候線程會複製主記憶體的變數到自己的本地記憶體。當本地記憶體變數改變時候就同步到主記憶體。如果有多個變數線程共用變數,這時候主記憶體又會重新整理同步所有線程的變數。而這種同步並不是即時的。

  

  如何和證明每個線程內部都有一份主記憶體副本?

  下面有段代碼

package com.mylienkd;public class MyThread implements Runnable {private  Integer nubmer=0;@Overridepublic void run() {while(true){if(nubmer>1){System.out.println(Thread.currentThread()+"子線程迴圈結束");break;}}}public void setNubmer(Integer nubmer) {this.nubmer = nubmer;}public static void main(String[] args) throws Exception {MyThread thread=new MyThread();new Thread(thread).start();//睡眠1sThread.sleep(1000);thread.setNubmer(10);//睡眠3sThread.sleep(3000);System.out.println("主線程結束");}}

 在此運行此代碼得到如下結果

  仔細觀察代碼以及結果可以發現,在主線程更改變數nubmer為10後,主線程執行結束,但是控制台並沒退出一直在執行。

  這是因為子線程並沒有退出迴圈。因為子執行緒區域記憶體的number為0,主記憶體中的值並沒有重新整理到子線程中的本記憶體的所以才會出現這種狀態。

  如何解決此方法。java為了避免這種情況提供了關鍵字volatile ,在number變數上加上volatile關鍵字

private volatile Integer nubmer=0;

  運行此代碼得到結果

  

可以看到此代碼在主線程退出前,子線程就先退出了迴圈。這是因為volatile關鍵字即時更新此變數。在number變數更改時,就同步重新整理更改其他線程的副本變數。

在很多地方叫做volatile關鍵字解決可見度。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.