高并發(fā)編程系列:并發(fā)容器的原理,7大并發(fā)容器詳解屯耸、及使用場(chǎng)景

并發(fā)容器的由來

在Java并發(fā)編程中慕趴,經(jīng)常聽到Java集合類泛啸,同步容器、并發(fā)容器,那么他們有哪些具體分類帝际,以及各自之間的區(qū)別和優(yōu)劣呢阔涉?

只有把這些梳理清楚了氯析,你才能真正掌握在高并發(fā)的環(huán)境下登失,正確使用好并發(fā)容器,我們先從Java集合類塔逃,同步容器談起讯壶。

并發(fā)容器詳細(xì)介紹

1.什么是同步容器

Java的集合容器框架中,主要有四大類別:List湾盗、Set伏蚊、Queue、Map格粪,大家熟知的這些集合類ArrayList丙挽、LinkedList肺孵、HashMap這些容器都是非線程安全的。

如果有多個(gè)線程并發(fā)地訪問這些容器時(shí)颜阐,就會(huì)出現(xiàn)問題。因此吓肋,在編寫程序時(shí)凳怨,在多線程環(huán)境下必須要求程序員手動(dòng)地在任何訪問到這些容器的地方進(jìn)行同步處理,這樣導(dǎo)致在使用這些容器的時(shí)候非常地不方便是鬼。

所以肤舞,Java先提供了同步容器供用戶使用。

同步容器可以簡(jiǎn)單地理解為通過synchronized來實(shí)現(xiàn)同步的容器均蜜,比如Vector李剖、Hashtable以及SynchronizedList等容器。

2.同步容器囤耳,主要的分類

  • Vector
  • Stack
  • HashTable
  • Collections.synchronized方法生成

同步容器面臨的問題

可以通過查看Vector篙顺,Hashtable等這些同步容器的實(shí)現(xiàn)代碼,可以看到這些容器實(shí)現(xiàn)線程安全的方式就是將它們的狀態(tài)封裝起來充择,并在需要同步的方法上加上關(guān)鍵字synchronized德玫。

這樣做的代價(jià)是削弱了并發(fā)性,當(dāng)多個(gè)線程共同競(jìng)爭(zhēng)容器級(jí)的鎖時(shí)椎麦,吞吐量就會(huì)降低宰僧。

例如: HashTable只要有一條線程獲取了容器的鎖之后,其他所有的線程訪問同步函數(shù)都會(huì)被阻塞观挎,因此同一時(shí)刻只能有一條線程訪問同步函數(shù)琴儿。

因此為了解決同步容器的性能問題,所以才有了并發(fā)容器嘁捷。

什么是并發(fā)容器

java.util.concurrent包中提供了多種并發(fā)類容器造成。

并發(fā)類容器是專門針對(duì)多線程并發(fā)設(shè)計(jì)的,使用了鎖分段技術(shù)普气,只對(duì)操作的位置進(jìn)行同步操作谜疤,但是其他沒有操作的位置其他線程仍然可以訪問,提高了程序的吞吐量现诀。

采用了CAS算法和部分代碼使用synchronized鎖保證線程安全夷磕。

并發(fā)容器有哪些分類

七大并發(fā)容器種類.jpg

1.ConcurrentHashMap

對(duì)應(yīng)的非并發(fā)容器:HashMap

目標(biāo):代替Hashtable、synchronizedMap仔沿,支持復(fù)合操作

原理:JDK6中采用一種更加細(xì)粒度的加鎖機(jī)制Segment“分段鎖”坐桩,JDK8中采用CAS無鎖算法。

2.CopyOnWriteArrayList

對(duì)應(yīng)的非并發(fā)容器:ArrayList

目標(biāo):代替Vector封锉、synchronizedList

原理:利用高并發(fā)往往是讀多寫少的特性绵跷,對(duì)讀操作不加鎖膘螟,對(duì)寫操作,先復(fù)制一份新的集合碾局,在新的集合上面修改荆残,然后將新集合賦值給舊的引用,并通過volatile 保證其可見性净当,當(dāng)然寫操作的鎖是必不可少的了内斯。

3.CopyOnWriteArraySet

對(duì)應(yīng)的非并發(fā)容器:HashSet

目標(biāo):代替synchronizedSet

原理:基于CopyOnWriteArrayList實(shí)現(xiàn),其唯一的不同是在add時(shí)調(diào)用的是CopyOnWriteArrayList的addIfAbsent方法像啼,其遍歷當(dāng)前Object數(shù)組俘闯,如Object數(shù)組中已有了當(dāng)前元素,則直接返回忽冻,如果沒有則放入Object數(shù)組的尾部真朗,并返回。

4.ConcurrentSkipListMap

對(duì)應(yīng)的非并發(fā)容器:TreeMap

目標(biāo):代替synchronizedSortedMap(TreeMap)

原理:Skip list(跳表)是一種可以代替平衡樹的數(shù)據(jù)結(jié)構(gòu)僧诚,默認(rèn)是按照Key值升序的遮婶。

5.ConcurrentSkipListSet

對(duì)應(yīng)的非并發(fā)容器:TreeSet

目標(biāo):代替synchronizedSortedSet

原理:內(nèi)部基于ConcurrentSkipListMap實(shí)現(xiàn)

6.ConcurrentLinkedQueue

不會(huì)阻塞的隊(duì)列

對(duì)應(yīng)的非并發(fā)容器:Queue

原理:基于鏈表實(shí)現(xiàn)的FIFO隊(duì)列(LinkedList的并發(fā)版本)

7.LinkedBlockingQueue、ArrayBlockingQueue振诬、PriorityBlockingQueue

對(duì)應(yīng)的非并發(fā)容器:BlockingQueue

特點(diǎn):拓展了Queue蹭睡,增加了可阻塞的插入和獲取等操作

原理:通過ReentrantLock實(shí)現(xiàn)線程安全,通過Condition實(shí)現(xiàn)阻塞和喚醒

實(shí)現(xiàn)類:

  • LinkedBlockingQueue:基于鏈表實(shí)現(xiàn)的可阻塞的FIFO隊(duì)列
  • ArrayBlockingQueue:基于數(shù)組實(shí)現(xiàn)的可阻塞的FIFO隊(duì)列
  • PriorityBlockingQueue:按優(yōu)先級(jí)排序的隊(duì)列

ConcurrentHashMap的實(shí)現(xiàn)

image

HashMap,Hashtable與ConcurrentHashMap都是實(shí)現(xiàn)的哈希表數(shù)據(jù)結(jié)構(gòu)赶么,在隨機(jī)讀取的時(shí)候效率很高肩豁。

Hashtable實(shí)現(xiàn)同步是利用synchronized關(guān)鍵字進(jìn)行鎖定的,其是針對(duì)整張哈希表進(jìn)行鎖定的辫呻,即每次鎖住整張表讓線程獨(dú)占清钥,在線程安全的背后是巨大的浪費(fèi)。

ConcurrentHashMap和Hashtable主要區(qū)別就是圍繞著鎖的粒度進(jìn)行區(qū)別以及如何區(qū)鎖定放闺。

上圖中祟昭,左邊是Hashtable的實(shí)現(xiàn)方式,可以看到鎖住整個(gè)哈希表怖侦;而右邊則是ConcurrentHashMap的實(shí)現(xiàn)方式篡悟,單獨(dú)鎖住每一個(gè)桶(segment).ConcurrentHashMap將哈希表分為16個(gè)桶(默認(rèn)值),諸如get(),put(),remove()等常用操作只鎖當(dāng)前需要用到的桶,而size()才鎖定整張表匾寝。

原來只能一個(gè)線程進(jìn)入搬葬,現(xiàn)在卻能同時(shí)接受16個(gè)寫線程并發(fā)進(jìn)入(寫線程需要鎖定,而讀線程幾乎不受限制)艳悔。

所以急凰,才有了并發(fā)性的極大提升。

高并發(fā)編程猜年,除了并發(fā)容器抡锈,還會(huì)涉及到并發(fā)工具類:CountDownLatch等疾忍,后續(xù)將詳細(xì)的介紹并發(fā)工具類,以及ConcurrentHashMap的底層實(shí)現(xiàn)細(xì)節(jié)床三,不僅要知其然,還要知其所以然一罩,這樣才能更好的掌握好高并發(fā)編程。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撇簿,一起剝皮案震驚了整個(gè)濱河市擒抛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌补疑,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歹撒,死亡現(xiàn)場(chǎng)離奇詭異莲组,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)暖夭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門锹杈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人迈着,你說我怎么就攤上這事竭望。” “怎么了裕菠?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵咬清,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我奴潘,道長(zhǎng)旧烧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任画髓,我火速辦了婚禮掘剪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奈虾。我一直安慰自己夺谁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布肉微。 她就那樣靜靜地躺著匾鸥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浪册。 梳的紋絲不亂的頭發(fā)上扫腺,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音村象,去河邊找鬼笆环。 笑死攒至,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的躁劣。 我是一名探鬼主播迫吐,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼账忘!你這毒婦竟也來了志膀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤鳖擒,失蹤者是張志新(化名)和其女友劉穎溉浙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒋荚,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡戳稽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了期升。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惊奇。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖播赁,靈堂內(nèi)的尸體忽然破棺而出颂郎,到底是詐尸還是另有隱情,我是刑警寧澤容为,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布乓序,位于F島的核電站,受9級(jí)特大地震影響舟奠,放射性物質(zhì)發(fā)生泄漏竭缝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一沼瘫、第九天 我趴在偏房一處隱蔽的房頂上張望抬纸。 院中可真熱鬧,春花似錦耿戚、人聲如沸湿故。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坛猪。三九已至,卻和暖如春皂股,著一層夾襖步出監(jiān)牢的瞬間墅茉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留就斤,地道東北人悍募。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像洋机,于是被迫代替她去往敵國(guó)和親坠宴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

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