java多線程——volatile關鍵字

提及volatile和sychronized這兩個關鍵字,學習過多線程的同窗應該都很熟悉,在jdk1.5以前,主要就是靠這兩個關鍵字來作多線程編程的,但在jdk1.5之後,多了一個java.util.concurrent(JUC)包,裏面包含了不少工具類用於多線程編程。但今天的重點仍是講講volatile關鍵字。java

多線程主要就是圍繞可見性和原子性這兩個特性展開的,volatile關鍵字對應着可見性,但不少時候人們誤覺得使用了volatile關鍵字後編寫多線程就沒問題了,不知道它不能保證原子性。編程

首先來講說什麼是可見性?

要說到可見性,就得扯到java內存模型了,暫且不作太多展開,簡單理解下就是,如今技術的提高,使得cpu的核心數不斷增多,而每一個核心又擁有本身的緩存,當處理數據時會有如下幾個步驟:緩存

  • 將數據從內存讀取到緩存中
  • 在緩存中對數據進行操做
  • 將緩存中的數據寫入內存中

步驟2中的操做並非原子性,也就是在步驟1以後,若是主內存變量發生修改以後,線程工做內存中的值因爲已經加載,不會產生對應的變化,因此計算出來的結果會和預期不同多線程

對於volatile修飾的變量,jvm虛擬機只是保證從主內存加載到線程工做內存的值是最新的jvm

正是由於這幾個步驟的存在,每每別的核心從內存中讀取到的數據不是最新的,這就形成了數據錯誤。java爲了屏蔽操做系統以及硬件之間的不一樣,在jvm中虛擬出了一套內存模型,編碼時使用volatile關鍵字對須要實時可見的數據修飾,在jvm底層會對該變量作特定的處理。工具

總結下可見性就是當多個線程操做共享數據時,保證操做的數據是最新的。性能

volatile關鍵字的做用?

剛也說過volatile關鍵字對應的可見性,但這是其中之一,它有兩個做用:學習

  • 1)使用volatile關鍵字修飾的變量,保證了其在多線程之間的可見性,即每次讀取到volatile變量,必定是最新的數據
  • 2)代碼底層執行不像咱們看到的高級語言—-Java程序這麼簡單,它的執行是Java代碼–>字節碼–>根據字節碼執行對應的C/C++代碼–>C/C++代碼被編譯成彙編語言–>和硬件電路交互,現實中,爲了獲取更好的性能JVM可能會對指令進行重排序,多線程下可能會出現一些意想不到的問題。使用volatile則會對禁止語義重排序,固然這也必定程度上下降了代碼執行效率
相關文章
相關標籤/搜索