深入理解Java多執行緒與併發框(第③篇)——Java記憶體模型與原子性、可見性、有序性
一、Java記憶體模型
Java Memory Modle,簡稱 JMM,中文名稱 Java記憶體模型,它是一個抽象的概念,用來描述或者規範訪問記憶體變數的方式。因為各中計算機的作業系統和硬體不同,方式機制也可能不同,Java記憶體模型用於遮蔽(適配)各種差異,以此來達到訪問各個平臺的一致的效果。這也是Java誇平臺的重要原因之一。
主記憶體: Java記憶體規定了所有變數都儲存在主記憶體(Main Memory)中,各個執行緒又有自己的本地記憶體(工作記憶體),本地記憶體儲存著主記憶體中部分變數。具體訪問方式如下:
JMM工作方式
- lock加鎖:為了保證訪問主記憶體變數的執行緒安全性,在訪問前一般會加鎖處理;
- read讀:從主記憶體中讀取一個變數到工作記憶體;
- load載入:把read讀到的變數載入到工作記憶體的變數副本中;
- use使用:此時執行緒可以使用其工作記憶體中的變數了;
- assign賦值:將處理後的變數賦值給工作記憶體中的變數;
- store儲存:將工作記憶體中的變數儲存到主記憶體中,以新建new 一個新變數的方式儲存;
- write寫:將store存在的新變數的引用賦值給被處理的變數;
- unload解鎖:所有的工作做完,最後解鎖釋放資源。
二、Java記憶體模型的三大特性
1. 原子性(Atomicity)
這裡的原子性如同資料庫事務中是原子性,一個或多個操作要麼全執行成功要麼全執行失敗(全不執行)。
int a = 1;
a++;
double b = 1.5;
Java記憶體模型只保證單一的操作具有原子性,比如上面的 int a = 1; 是一個單子的操作,所以具有原子性。而 a++ 操作在底層會分為三個操作:1)、讀取a的值給臨時變數;2)、臨時變數a的值加1操作;3)、將加操作後的值賦值給a。每個操作都是原子的,但Java記憶體模型在多執行緒下並不能保證多操作具有整體原子性,因為它也不知道這個整體內有多少操作,使用者想要達到多操作具有整體原子性,需要對響應的程式碼塊做同步(synchronous)處理,比如使用 有鎖的synchronized 或 無鎖的CAS。
2. 可見性(Visibility)
這裡的可見性是記憶體可見性。
如上圖,執行緒1和執行緒2在未同步的情況下對共享記憶體(主記憶體)中的變數進行訪問,比如兩個執行緒的操作都是對變數a進行加1操作。假設執行緒1首先獲取主記憶體中變數a的值,隨後執行緒2又獲取了主記憶體變數a的值,此時它們工作記憶體中a的值都是1,它們各自將a的值加1操作,然後assign至工作記憶體,工作記憶體中變數a的值都是2,然後兩個執行緒又將值重新整理到主記憶體,最後的結果是主記憶體中變數a的值是2。雖然整體對a的值加1操作做了兩次操作,但由於執行緒間的操作是互相隔離的,預設情況下無法感知記憶體變數的值在隨後的變化,也就無法訪問記憶體中最新的變數值,這就是記憶體可行性的問題。
如何解決記憶體可見性的問題?
- 對進入臨界區的執行緒做同步處理(比如 synchronized),同一時刻僅有一個執行緒能夠訪問臨界區的資源;
- 使用 volatile 關鍵字保證記憶體可見性,它能保證訪問臨界區資源的所有執行緒總能看到共享資源的最新值;
- CAS無鎖化。
3. 有序性(Ordering)
執行緒內的所有操作都是有序的,既程式執行的順序按照程式碼的先後順序執行。比如下面的示例:
int a = 1;
int b = 2;
int c = a + b;
執行緒內程式會先執行 int a = 1; ,然後執行 int b = 2; 最後執行int c = a + b;。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69964492/viewspace-2682073/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- java多執行緒3:原子性,可見性,有序性Java執行緒
- 深入理解Java多執行緒與併發框(第⑧篇)——深入理解:CASJava執行緒
- 「跬步千里」詳解 Java 記憶體模型與原子性、可見性、有序性Java記憶體模型
- Java併發之原子性、有序性、可見性Java
- 深入理解Java多執行緒與併發框(第①篇)——執行緒的狀態Java執行緒
- 深入理解Java多執行緒與併發框(第⑪篇)——執行緒池引數Java執行緒
- 深入理解Java多執行緒與併發框(第⑦篇)——volatile 關鍵字Java執行緒
- [深入理解Java虛擬機器]原子性/可見性/有序性Java虛擬機
- 執行緒安全性-原子性、可見性、有序性執行緒
- 【Java併發入門】02 Java記憶體模型:看Java如何解決可見性和有序性問題Java記憶體模型
- 【多執行緒與高併發原理篇:3_java記憶體模型】執行緒Java記憶體模型
- 深入理解Java多執行緒與併發框(第④篇)——重排序、屏障指令、as-if-serial規則Java執行緒排序
- 深入理解Java多執行緒與併發框(第⑩篇)——併發輔助工具類(很好的玩的工具類)Java執行緒
- 深入理解Java多執行緒與併發框(完結篇)——看完再不懂多執行緒我跪鍵盤Java執行緒
- Java併發程式設計-解決可見性與有序性問題Java程式設計
- Java併發程式設計Bug源頭:可見性、原子性和有序性問題Java程式設計
- 記一次對Java多執行緒記憶體可見性的測試Java執行緒記憶體
- Java多執行緒記憶體模型Java執行緒記憶體模型
- 【重學Java】多執行緒進階(執行緒池、原子性、併發工具類)Java執行緒
- 高階java必須清楚的概念:原子性、可見性、有序性Java
- Java併發程式設計-併發程式設計的Bug源頭:可見性、原子性和有序性問題Java程式設計
- Java多執行緒之記憶體模型Java執行緒記憶體模型
- Java高併發與多執行緒(三)-----執行緒的基本屬性和主要方法Java執行緒
- Java併發指南2:深入理解Java記憶體模型JMMJava記憶體模型
- volatile 可見性與原子性
- 你還不懂可見性、有序性和原子性?
- Java 執行緒記憶體模型Java執行緒記憶體模型
- Java虛擬機器08——Java記憶體模型與執行緒Java虛擬機記憶體模型執行緒
- 深入理解Java的堆記憶體和執行緒記憶體Java記憶體執行緒
- 併發程式設計之volatile與JMM多執行緒記憶體模型程式設計執行緒記憶體模型
- java多執行緒與併發 - 併發工具類Java執行緒
- Java多執行緒與併發之ThreadLocalJava執行緒thread
- 多執行緒之Java記憶體模型(JMM)(一)執行緒Java記憶體模型
- java多執行緒與併發 - 執行緒池詳解Java執行緒
- Java併發指南1:併發基礎與Java多執行緒Java執行緒
- 深入理解JVM(③)執行緒與Java的執行緒JVM執行緒Java
- 三大性質總結:原子性、可見性以及有序性
- java併發筆記之java執行緒模型Java筆記執行緒模型