Java ConcurrentHashMap源碼分析 JDK1.6

簡介

與ConcurrentHashMap類似的Java Conllections還有Hashtable和HashMap罩润,HashMap不是一個(gè)線程安全的類猜旬,key和value的值都可以是null沉眶,ConcurrentHashMap和HashMap都是線程安全的類球匕,但是key和value的值都不能是null。Hashtable保證線程安全的做法是每個(gè)可調(diào)用的方法都是synchronized的施掏。這意味著每個(gè)線程訪問Hashtable時(shí)都會(huì)把整個(gè)Hashtable鎖起來层宫。
> HashMap和HashTable的結(jié)構(gòu)圖:

HashMap和HashTable的結(jié)構(gòu)圖.png

??根據(jù)上圖可以看出同步的Hash容器是同步使用鎖來保證的,并且所有同步操作使用的是同一個(gè)鎖對象其监。這樣若有n個(gè)線程同時(shí)在get時(shí),這n個(gè)線程要串行的等待來獲取鎖限匣。(效率很低!)

ConcurrentHashMap則采用了分段鎖(Segment)的機(jī)制抖苦,使得競態(tài)條件只發(fā)生在Segment內(nèi)毁菱,增加了并發(fā)度;同時(shí)锌历,在HashMap.Entry的基礎(chǔ)上進(jìn)行改進(jìn)贮庞,ConcurrentHashMap.Entry的value和next域都是volatile的,可以保證在多線程環(huán)境下對于其他線程的可見性究西。由于ConcurrentHashMap不是對整個(gè)表加鎖窗慎,在執(zhí)行size()這些全局性質(zhì)的方法時(shí)需要遍歷整個(gè)Segment數(shù)組。


ConcurrentHashMap 的結(jié)構(gòu)分析

為了更好的理解 ConcurrentHashMap 高并發(fā)的具體實(shí)現(xiàn)卤材,讓我們先探索它的結(jié)構(gòu)模型遮斥。
??ConcurrentHashMap 類中包含兩個(gè)靜態(tài)內(nèi)部類 HashEntry 和 Segment。HashEntry 用來封裝映射表的鍵 / 值對扇丛;Segment 用來充當(dāng)鎖的角色术吗,每個(gè) Segment 對象守護(hù)整個(gè)散列映射表的若干個(gè)桶。每個(gè)桶是由若干個(gè) HashEntry 對象鏈接起來的鏈表帆精。一個(gè) ConcurrentHashMap 實(shí)例中包含由若干個(gè) Segment 對象組成的數(shù)組较屿。

HashEntry 類

HashEntry 用來封裝散列映射表中的鍵值對,在 HashEntry 類中,key卓练,hash 和 next 域都被聲明為 final 型隘蝎,value 域被聲明為 volatile 型。
<pre><code>static final class HashEntry<K, V> {

final int hash;
final K key;
volatile V value;
volatile HashEntry<K, V> next;
}</code></pre>

Segment 類

Segment 類繼承于 ReentrantLock 類襟企,從而使得 Segment 對象能充當(dāng)鎖的角色嘱么。每個(gè) Segment 對象用來守護(hù)其(成員對象 table 中)包含的若干個(gè)桶。
table 是一個(gè)由 HashEntry 對象組成的數(shù)組整吆。table 數(shù)組的每一個(gè)數(shù)組成員就是散列映射表的一個(gè)桶拱撵。
count 變量是一個(gè)計(jì)數(shù)器,它表示每個(gè) Segment 對象管理的 table 數(shù)組(若干個(gè) HashEntry 組成的鏈表)包含的 HashEntry 對象的個(gè)數(shù)表蝙。每一個(gè) Segment 對象都有一個(gè) count 對象來表示本 Segment 中包含的 HashEntry 對象的總數(shù)拴测。注意,之所以在每個(gè) Segment 對象中包含一個(gè)計(jì)數(shù)器府蛇,而不是在 ConcurrentHashMap 中使用全局的計(jì)數(shù)器集索,是為了避免出現(xiàn)“熱點(diǎn)域”而影響 ConcurrentHashMap 的并發(fā)性。
Segment 類的定義:
<pre><code>static final class Segment<K, V> extends ReentrantLock implements Serializable {
//在本 segment 范圍內(nèi)汇跨,包含的 HashEntry 元素的個(gè)數(shù)
transient volatile int count;

//table 被更新的次數(shù)
transient int modCount;

//當(dāng) table 中包含的 HashEntry 元素的個(gè)數(shù)超過本變量值時(shí),觸發(fā) table 的再散列resize
transient int threshold;

//裝載因子
final float loadFactor;

//table 是由 HashEntry 對象組成的數(shù)組
transient volatile HashEntry<K,V>[] table;
}
</code></pre>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末务荆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子穷遂,更是在濱河造成了極大的恐慌函匕,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚪黑,死亡現(xiàn)場離奇詭異盅惜,居然都是意外死亡中剩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門抒寂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來结啼,“玉大人,你說我怎么就攤上這事屈芜〗祭ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵井佑,是天一觀的道長属铁。 經(jīng)常有香客問我,道長毅糟,這世上最難降的妖魔是什么红选? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮姆另,結(jié)果婚禮上喇肋,老公的妹妹穿的比我還像新娘。我一直安慰自己迹辐,他們只是感情好蝶防,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著明吩,像睡著了一般间学。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上印荔,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天低葫,我揣著相機(jī)與錄音,去河邊找鬼仍律。 笑死嘿悬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的水泉。 我是一名探鬼主播善涨,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼草则!你這毒婦竟也來了钢拧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤炕横,失蹤者是張志新(化名)和其女友劉穎源内,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體份殿,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姿锭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年塔鳍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呻此。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖腔寡,靈堂內(nèi)的尸體忽然破棺而出焚鲜,到底是詐尸還是另有隱情,我是刑警寧澤放前,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布忿磅,位于F島的核電站,受9級特大地震影響凭语,放射性物質(zhì)發(fā)生泄漏葱她。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一似扔、第九天 我趴在偏房一處隱蔽的房頂上張望吨些。 院中可真熱鬧,春花似錦炒辉、人聲如沸豪墅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偶器。三九已至,卻和暖如春缝裤,著一層夾襖步出監(jiān)牢的瞬間屏轰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工憋飞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留霎苗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓搀崭,卻偏偏與公主長得像叨粘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子瘤睹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容

  • Java SE 基礎(chǔ): 封裝升敲、繼承、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體轰传,并盡...
    Jayden_Cao閱讀 2,103評論 0 8
  • Java8張圖 11驴党、字符串不變性 12、equals()方法获茬、hashCode()方法的區(qū)別 13港庄、...
    Miley_MOJIE閱讀 3,697評論 0 11
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等倔既,對于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,490評論 0 3
  • 我們了解到關(guān)于 HashMap 和 Hashtable 這兩種集合。其中 HashMap 是非線程安全的鹏氧,當(dāng)我們只...
    曹振華閱讀 1,059評論 0 9
  • 美國保險(xiǎn)業(yè)務(wù)的推銷遇到了難題把还,成千上萬的業(yè)務(wù)員实蓬,走千家,串萬戶吊履,使得各個(gè)家庭的主人安皱、主婦們產(chǎn)生厭煩。他(她)們或者...
    財(cái)商故事會(huì)閱讀 320評論 0 0