[轉(zhuǎn)]如何在java中使用ConcurrentHashMap

原文地址

ConcurrentHashMap(簡稱CHM)是在Java 1.5作為Hashtable的替代選擇新引入的妇智,是concurrent包的重要成員曹阔。在Java 1.5之前只冻,如果想要實現(xiàn)一個可以在多線程和并發(fā)的程序中安全使用的Map,只能在HashTable和synchronized Map中選擇,因為HashMap并不是線程安全的。但再引入了CHM之后,我們有了更好的選擇唯卖。CHM不但是線程安全的,而且比HashTable和synchronizedMap的性能要好躬柬。相對于HashTable和synchronizedMap鎖住了整個Map拜轨,CHM只鎖住部分Map。CHM允許并發(fā)的讀操作允青,同時通過同步鎖在寫操作時保持數(shù)據(jù)完整性橄碾。我們已經(jīng)在Top 5 Java Concurrent Collections from JDK 5 and 6中學習了CHM的基礎知識,在這篇博客中我將介紹以下幾點:

CHM在Java中如何實現(xiàn)的

什么情況下應該使用CHM

在Java中使用CHM的例子

CHM的一些重要特性

Java中ConcurrentHashMap的實現(xiàn)

CHM引入了分割颠锉,并提供了HashTable支持的所有的功能堪嫂。在CHM中,支持多線程對Map做讀操作木柬,并且不需要任何的blocking。這得益于CHM將Map分割成了不同的部分淹办,在執(zhí)行更新操作時只鎖住一部分眉枕。根據(jù)默認的并發(fā)級別(concurrency level),Map被分割成16個部分怜森,并且由不同的鎖控制速挑。這意味著,同時最多可以有16個寫線程操作Map副硅。試想一下姥宝,由只能一個線程進入變成同時可由16個寫線程同時進入(讀線程幾乎不受限制),性能的提升是顯而易見的恐疲。但由于一些更新操作腊满,如put(),remove(),putAll(),clear()只鎖住操作的部分,所以在檢索操作不能保證返回的是最新的結(jié)果培己。

另一個重要點是在迭代遍歷CHM時碳蛋,keySet返回的iterator是弱一致和fail-safe的,可能不會返回某些最近的改變省咨,并且在遍歷過程中肃弟,如果已經(jīng)遍歷的數(shù)組上的內(nèi)容變化了,不會拋出ConcurrentModificationExceptoin的異常。

CHM默認的并發(fā)級別是16笤受,但可以在創(chuàng)建CHM時通過構造函數(shù)改變穷缤。毫無疑問,并發(fā)級別代表著并發(fā)執(zhí)行更新操作的數(shù)目箩兽,所以如果只有很少的線程會更新Map津肛,那么建議設置一個低的并發(fā)級別。另外比肄,CHM還使用了ReentrantLock來對segments加鎖快耿。

Java中ConcurrentHashMap putifAbsent方法的例子

很多時候我們希望在元素不存在時插入元素,我們一般會像下面那樣寫代碼

上面這段代碼在HashMap和HashTable中是好用的芳绩,但在CHM中是有出錯的風險的掀亥。這是因為CHM在put操作時并沒有對整個Map加鎖,所以一個線程正在put(k,v)的時候妥色,另一個線程調(diào)用get(k)會得到null搪花,這就會造成一個線程put的值會被另一個線程put的值所覆蓋。當然嘹害,你可以將代碼封裝到synchronized代碼塊中撮竿,這樣雖然線程安全了,但會使你的代碼變成了單線程笔呀。CHM提供的putIfAbsent(key,value)方法原子性的實現(xiàn)了同樣的功能幢踏,同時避免了上面的線程競爭的風險。

什么時候使用ConcurrentHashMap

CHM適用于讀者數(shù)量超過寫者時许师,當寫者數(shù)量大于等于讀者時房蝉,CHM的性能是低于Hashtable和synchronized Map的。這是因為當鎖住了整個Map時微渠,讀操作要等待對同一部分執(zhí)行寫操作的線程結(jié)束搭幻。CHM適用于做cache,在程序啟動時初始化,之后可以被多個請求線程訪問逞盆。正如Javadoc說明的那樣檀蹋,CHM是HashTable一個很好的替代,但要記住云芦,CHM的比HashTable的同步性稍弱俯逾。

總結(jié)

現(xiàn)在我們知道了什么是ConcurrentHashMap和什么時候該用ConcurrentHashMap,下面我們來復習一下CHM的一些關鍵點焕数。

CHM允許并發(fā)的讀和線程安全的更新操作

在執(zhí)行寫操作時纱昧,CHM只鎖住部分的Map

并發(fā)的更新是通過內(nèi)部根據(jù)并發(fā)級別將Map分割成小部分實現(xiàn)的

高的并發(fā)級別會造成時間和空間的浪費,低的并發(fā)級別在寫線程多時會引起線程間的競爭

CHM的所有操作都是線程安全

CHM返回的迭代器是弱一致性堡赔,fail-safe并且不會拋出ConcurrentModificationException異常

CHM不允許null的鍵值

可以使用CHM代替HashTable识脆,但要記住CHM不會鎖住整個Map

以上就是Java中CHM的實現(xiàn)和使用場景

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子灼捂,更是在濱河造成了極大的恐慌离例,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悉稠,死亡現(xiàn)場離奇詭異宫蛆,居然都是意外死亡,警方通過查閱死者的電腦和手機的猛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門耀盗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人卦尊,你說我怎么就攤上這事叛拷。” “怎么了岂却?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵忿薇,是天一觀的道長。 經(jīng)常有香客問我躏哩,道長署浩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任扫尺,我火速辦了婚禮筋栋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘正驻。我一直安慰自己二汛,他們只是感情好,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布拨拓。 她就那樣靜靜地躺著,像睡著了一般氓栈。 火紅的嫁衣襯著肌膚如雪渣磷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天授瘦,我揣著相機與錄音醋界,去河邊找鬼。 笑死提完,一個胖子當著我的面吹牛形纺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播徒欣,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼逐样,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脂新,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤挪捕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后争便,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體级零,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年滞乙,在試婚紗的時候發(fā)現(xiàn)自己被綠了奏纪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡斩启,死狀恐怖序调,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浇垦,我是刑警寧澤炕置,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站男韧,受9級特大地震影響朴摊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜此虑,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一粱腻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧幢痘,春花似錦褥符、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恩伺,卻和暖如春赴背,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晶渠。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工凰荚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人褒脯。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓便瑟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親番川。 傳聞我的和親對象是個殘疾皇子到涂,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

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

  • Java SE 基礎: 封裝脊框、繼承、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務)結(jié)合為一個獨立的整體养盗,并盡...
    Jayden_Cao閱讀 2,112評論 0 8
  • 從三月份找實習到現(xiàn)在缚陷,面了一些公司,掛了不少往核,但最終還是拿到小米箫爷、百度、阿里聂儒、京東虎锚、新浪、CVTE衩婚、樂視家的研發(fā)崗...
    時芥藍閱讀 42,278評論 11 349
  • Java8張圖 11窜护、字符串不變性 12、equals()方法非春、hashCode()方法的區(qū)別 13柱徙、...
    Miley_MOJIE閱讀 3,709評論 0 11
  • 姓名:王成茗 日精進打卡第3天 【打卡始于2017.10.12持續(xù)于2017.10.14】 【知~學習】 ...
    王成茗閱讀 188評論 0 0
  • 2017年1月8日。今天的行程很單純奇昙,就是鼓浪嶼护侮。8點出門,8點50的輪渡储耐,李先生說怕來不及只好讓我?guī)е琰c等...
    北方的愔格閱讀 877評論 3 4