ConcurrentHashMap、HashMap和HashTable

HashMap姐刁、HashTable與ConcurrentHashMap

1芥牌、HashMap是非線程安全的,HashTable是線程安全的聂使。

2壁拉、HashMap的鍵和值都允許有null值存在,而HashTable則不行岩遗。

3扇商、因為線程安全的問題,HashMap效率比HashTable的要高宿礁。

4案铺、ConcurrentHashMap線程安全,加入segment梆靖,每個segment通過lock的方式實現(xiàn)線程安全控汉,避免整個數(shù)據(jù)的訪問加同步鎖,降低效率返吻。

一姑子、HashMap的內(nèi)部存儲結(jié)構(gòu)

Java中數(shù)據(jù)存儲方式最底層的兩種結(jié)構(gòu),一種是數(shù)組测僵,另一種就是鏈表街佑,數(shù)組的特點:連續(xù)空間,尋址迅速捍靠,但是在刪除或者添加元素的時候需要有較大幅度的移動沐旨,所以查詢速度快,增刪較慢榨婆。而鏈表正好相反磁携,由于空間不連續(xù),尋址困難良风,增刪元素只需修改指針谊迄,所以查詢慢、增刪快烟央。有沒有一種數(shù)據(jù)結(jié)構(gòu)來綜合一下數(shù)組和鏈表统诺,以便發(fā)揮他們各自的優(yōu)勢?答案是肯定的吊档!就是:哈希表篙议。哈希表具有較快(常量級)的查詢速度,及相對較快的增刪速度怠硼,所以很適合在海量數(shù)據(jù)的環(huán)境中使用鬼贱。一般實現(xiàn)哈希表的方法采用“拉鏈法”,我們可以理解為“鏈表的數(shù)組”香璃,如下圖:

從上圖中这难,我們可以發(fā)現(xiàn)哈希表是由數(shù)組+鏈表組成的,一個長度為16的數(shù)組中葡秒,每個元素存儲的是一個鏈表的頭結(jié)點姻乓。那么這些元素是按照什么樣的規(guī)則存儲到數(shù)組中呢。一般情況是通過hash(key)%len獲得眯牧,也就是元素的key的哈希值對數(shù)組長度取模得到蹋岩。比如上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12学少。所以12剪个、28、108以及140都存儲在數(shù)組下標為12的位置版确。它的內(nèi)部其實是用一個Entity數(shù)組來實現(xiàn)的扣囊,屬性有key、value绒疗、next侵歇。接下來我會從初始化階段詳細的講解HashMap的內(nèi)部結(jié)構(gòu)。

二吓蘑、HashTable的內(nèi)部存儲結(jié)構(gòu)

HashTable和HashMap采用相同的存儲機制惕虑,二者的實現(xiàn)基本一致,不同的是:

1磨镶、HashMap是非線程安全的溃蔫,HashTable是線程安全的,內(nèi)部的方法基本都是synchronized棋嘲。

2酒唉、HashTable不允許有null值的存在。

在HashTable中調(diào)用put方法時沸移,如果key為null痪伦,直接拋出NullPointerException。其它細微的差別還有雹锣,比如初始化Entry數(shù)組的大小等等网沾,但基本思想和HashMap一樣。

通過分析Hashtable就知道蕊爵,synchronized是針對整張Hash表的辉哥,即每次鎖住整張表讓線程獨占

三、ConcurrentHashMap的內(nèi)部存儲結(jié)構(gòu)

ConcurrentHashMap允許多個修改操作并發(fā)進行,其關(guān)鍵在于使用了鎖分離技術(shù)醋旦。它使用了多個鎖來控制對hash表的不同部分進行的修改恒水。ConcurrentHashMap內(nèi)部使用段(Segment)來表示這些不同的部分,每個段其實就是一個小的hash table饲齐,它們有自己的鎖钉凌。只要多個修改操作發(fā)生在不同的段上,它們就可以并發(fā)進行捂人。

有些方法需要跨段御雕,比如size()和containsValue(),它們可能需要鎖定整個表而而不僅僅是某個段滥搭,這需要按順序鎖定所有段酸纲,操作完畢后,又按順序釋放所有段的鎖瑟匆。這里“按順序”是很重要的闽坡,否則極有可能出現(xiàn)死鎖,在ConcurrentHashMap內(nèi)部脓诡,段數(shù)組是final的无午,并且其成員變量實際上也是final的,但是祝谚,僅僅是將數(shù)組聲明為final的并不保證數(shù)組成員也是final的宪迟,這需要實現(xiàn)上的保證。這可以確保不會出現(xiàn)死鎖交惯,因為獲得鎖的順序是固定的次泽。

一、結(jié)構(gòu)解析

ConcurrentHashMap和Hashtable主要區(qū)別就是圍繞著鎖的粒度以及如何鎖,可以簡單理解成把一個大的HashTable分解成多個席爽,形成了鎖分離意荤。如圖:

而Hashtable的實現(xiàn)方式是---鎖整個hash表

二、應(yīng)用場景

當有一個大數(shù)組時需要在多個線程共享時就可以考慮是否把它給分層多個節(jié)點了只锻,避免大鎖玖像。并可以考慮通過hash算法進行一些模塊定位。

其實不止用于線程齐饮,當設(shè)計數(shù)據(jù)表的事務(wù)時(事務(wù)某種意義上也是同步機制的體現(xiàn))捐寥,可以把一個表看成一個需要同步的數(shù)組,如果操作的表數(shù)據(jù)太多時就可以考慮事務(wù)分離了(這也是為什么要避免大表的出現(xiàn))祖驱,比如把數(shù)據(jù)進行字段拆分握恳,水平分表等.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市捺僻,隨后出現(xiàn)的幾起案子乡洼,更是在濱河造成了極大的恐慌崇裁,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件束昵,死亡現(xiàn)場離奇詭異拔稳,居然都是意外死亡,警方通過查閱死者的電腦和手機妻怎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門壳炎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泞歉,“玉大人逼侦,你說我怎么就攤上這事⊙遥” “怎么了榛丢?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長挺庞。 經(jīng)常有香客問我晰赞,道長,這世上最難降的妖魔是什么选侨? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任掖鱼,我火速辦了婚禮,結(jié)果婚禮上援制,老公的妹妹穿的比我還像新娘戏挡。我一直安慰自己,他們只是感情好晨仑,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布褐墅。 她就那樣靜靜地躺著,像睡著了一般洪己。 火紅的嫁衣襯著肌膚如雪妥凳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天答捕,我揣著相機與錄音逝钥,去河邊找鬼。 笑死拱镐,一個胖子當著我的面吹牛艘款,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痢站,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼磷箕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了阵难?” 一聲冷哼從身側(cè)響起岳枷,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后空繁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殿衰,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年盛泡,在試婚紗的時候發(fā)現(xiàn)自己被綠了闷祥。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡傲诵,死狀恐怖凯砍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拴竹,我是刑警寧澤悟衩,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站栓拜,受9級特大地震影響座泳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜幕与,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一挑势、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧啦鸣,春花似錦潮饱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝙搔,卻和暖如春缕溉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吃型。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工证鸥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人勤晚。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓枉层,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赐写。 傳聞我的和親對象是個殘疾皇子鸟蜡,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

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