double pi = 3.14; //A double r = 1.0; //B double area = pi * r * r; //C
一、A -> B //不知足happens- before,不會改變程序執行結果數組
二、B -> C //happens- before, 會改變程序執行結果數據結構
三、A -> C //happens- before, 會改變程序執行結果多線程
JMM會對1進行重排序,二、3不會;併發
在一個線程內,app
按照代碼順序,同個字段,書寫在前面的操做先行發生於書寫在後面的操做spa
在多線程併發中:線程
對一個monitor的解鎖操做happens-before後續對同一個monitor的加鎖操做」、code
「對某個volatile字段的寫操做happens-before後續對同一個volatile字段的讀操做blog
ConcurrentHashMap排序
Segment裏有兩個volatile變量:count和table;HashEntry裏有一個volatile變量:value。
get方法弱一致性
含義:往ConcurrentHashMap底層數據結構中加入一個元素後,不能立馬對get可見。換句話說,put操做將一個元素加入到底層數據結構後,get可能在某段時間內還看不到這個元素;
由於get方法未加鎖,get方法可能會在put方法的執行過程當中被調用,這就是get操做是弱一致的根本緣由;
另外,在put方法調用結束的時候,get方法必定能獲取到值,這是如何保證的呢,由於有一個volatile修飾的變量count的存在,put結束的時候,會寫入count,get開始的時候會讀取count,這裏存在happens- before關係
(對某個volatile字段的寫操做happens-before後續對同一個volatile字段的讀操做);
可是,由於get方法未加鎖,因此不能保證在put方法調用結束的時候調用get,可能在中間時刻調用(即便put方法已經賦值完成),致使不存在happens- before關係,可能會由於指令重排等緣由不能及時獲得值;
迭代器弱一致性表現
在遍歷過程當中,若是已經遍歷的數組上的內容變化了,迭代器不會拋出ConcurrentModificationException異常。
由於未加鎖,若是未遍歷的數組上的內容發生了變化,則有可能反映到迭代過程當中,與get相似;