線程、多線程之volatile關鍵字

1. 講一下Java內存模型

       在 JDK1.2 之前,Java的內存模型實現總是從主存(即共享內存)讀取變量,是不需要進行特別的注意的。而在當前的 Java 內存模型下,線程可以把變量保存本地內存(比如機器的寄存器,線程私有)中,而不是直接在主存中進行讀寫。這就可能造成一個線程在主存中修改了一個變量的值,而另外一個線程還繼續使用它在寄存器中的變量值的拷貝,造成數據的不一致

數據不一致

       要解決這個問題,就需要把變量聲明爲volatile,這就指示 JVM,這個變量是不穩定的,每次有線程使用它都會到主內存中進行讀取。說白了, volatile 關鍵字的主要作用就是保證變量的可見性,然後還有一個作用是防止指令重排序(上一篇已粗略描述過)。

volatile關鍵字的可見性

2. 併發編程的三個重要特性

  1. 原子性 : 一個的操作或者多次操作,要麼所有的操作全部都得到執行並且不會收到任何因素的干擾而中斷,要麼所有的操作都執行,要麼都不執行。synchronized 可以保證代碼片段的原子性。
  2. 可見性 :當一個變量對共享變量進行了修改,那麼另外的線程都是立即可以看到修改後的最新值。volatile 關鍵字可以保證共享變量的可見性。
  3. 有序性 :代碼在執行的過程中的先後順序,Java 在編譯器以及運行期間的優化,代碼的執行順序未必就是編寫代碼時候的順序。volatile 關鍵字可以禁止指令進行重排序優化。

3. synchronized 關鍵字和 volatile 關鍵字的區別

synchronized 關鍵字和 volatile 關鍵字是兩個互補的存在,而不是對立的存在:

  • volatile關鍵字是線程同步的輕量級實現,所以volatile性能肯定比synchronized關鍵字要好。但是volatile關鍵字只能用於變量而synchronized關鍵字可以修飾方法以及代碼塊。synchronized關鍵字在JavaSE1.6之後進行了主要包括爲了減少獲得鎖和釋放鎖帶來的性能消耗而引入的偏向鎖和輕量級鎖以及其它各種優化之後執行效率有了顯著提升,實際開發中使用 synchronized 關鍵字的場景還是更多一些
  • 多線程訪問volatile關鍵字不會發生阻塞,而synchronized關鍵字可能會發生阻塞;
  • volatile關鍵字能保證數據的可見性,但不能保證數據的原子性。synchronized關鍵字兩者都能保證;
  • volatile關鍵字主要用於解決變量在多個線程之間的可見性,而 synchronized關鍵字解決的是多個線程之間訪問資源的同步性。

如有披露或問題歡迎留言或者入羣探討

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章