JAVA並發編程4_線程同步之volatile關鍵字

來源:互聯網
上載者:User

標籤:多線程   java   並發   

上一篇部落格JAVA並發編程3_線程同步之synchronized關鍵字中講解了JAVA中保證線程同步的關鍵字synchronized,其實JAVA裡面還有個較弱的同步機制volatile。volatile關鍵字是JAVA中的輕量級的同步機制,用來將變數的更新操作同步到其他線程。從記憶體可見度的角度來說,寫入volatile變數相當於退出同步代碼塊,讀取volatile變數相當於進入同步代碼塊。

舊的記憶體模型:保證讀寫volatile都直接發生在main memory中。

在新的記憶體模型下(1.5)對volatile的語義進行了修補和增強:如果當線程 A 寫入 volatile 變數 V 而線程 B 讀取 V 時,那麼在寫入 V 時,A 可見的所有變數值現在都可以保證對 B 是可見的。

一句話:volatile保證可見度,但不能保證原子性。

原子性的:一組語句作為一個不可分割的單元被執行。任何一個執行同步代碼塊的線程,都不可能看到有其他線程正在執行由同一個鎖保護的同步代碼塊。volatile變數的非原子性最容易被忽略。

可見度:指一個線程修改了一個共用變數的值,其他線程能夠立即得知這個修改。

volatile的非原子性

變數被定義為volatile並不能保證對其所有操作是原子的,由於非原子性,因此volatile並不能保證多線程並發的安全性。如下面的代碼:

public class Test implements Runnable{public volatile int race = 0;@Overridepublic void run() {increase();}private void increase() {race ++;}public static void main(String[] args) {Test t = new Test();Thread [] threads = new Thread[1000];for (int i = 0; i < 1000; i++) {threads[i] = new Thread(t);threads[i].start();}while (Thread.activeCount() > 1) {Thread.yield();}// 保證列印的時候1000個線程都已經執行完畢System.out.println(t.race);}}

這段代碼開啟了1000個線程,對race變數進行自增操作。理論上,安全執行緒的話,執行結果應該是1000。但實際上執行得到的結果都是一個小於1000的值。

分析一下上面案的代碼,問題就出在了race++這句代碼。它不是原子操作。這句代碼實際上是分為三個操作的:讀取race的值、進行加1操作、寫入新的值。

顯然可以看出來,將變數定義成vilatile也不能保證原子性:

線程1先讀取了變數race的原始值,然後線程1被阻塞了;線程2也去讀取變數race的原始值,然後進行加1操作,並把+1後的值寫入工作記憶體,最後寫入主存,然後線程1接著進行加1操作,由於已經讀取了race的值,此時線上程1的工作記憶體中race的值仍然是之前的值,所以線程1對race進行加1操作後的值和剛才一樣,然後將這個值寫入工作記憶體,最後寫入主存。這樣就出現了兩個線程自增完後其實只加了一次。究其原因是因為volatile不能保證原子性。

可以將自增操作改為同步代碼塊即可解決。

private synchronized void increase() {race ++;}
volatile的可見度

一個線程修改了某個volatile變數的值,這新值對其他線程來說是立即可見的。

boolean ready;// thread 1while (!ready) {       doSomthing();}// thread2ready = true;

這是銷毀線程的通用方法。但是存在問題是ready變數改為true還沒來得及寫入主存,就轉到其他線程執行了,這時還會進入迴圈。這時,volatile的作用就體現出來了。volatile變數保證了他在一個線程裡面修改後會立即被其他線程得知。

volatile變數的使用情境這篇文章寫得很詳細:Java 理論與實踐: 正確使用 Volatile 變數

JAVA並發編程4_線程同步之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.