重排序、hb、ConcurrentHashMap弱一致性(jdk1.6)

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變量:counttable;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相似;

相關文章
相關標籤/搜索