同步類容器與并發(fā)類容器

同步容器類

  • 同步容器類Vector 和 Hashtable 他宛,以及一些由 Collections.synchronizedXxx 等工廠方法創(chuàng)建的隔心。其底層的機(jī)制無非是用傳統(tǒng)的synchronized 關(guān)鍵字對每一個公用的方法都進(jìn)行同步喜颁,使得每次只能有一個線程訪問容器的狀態(tài)填硕。這很明顯不滿足我們今天互聯(lián)網(wǎng)時代的高并發(fā)的需求耘戚,在保證線程安全的同事缕陕,也必須要有足夠好的性能峻仇。

  • 同步類容器都是線程安全的篮洁,但在某些場景下需要加鎖來保護(hù)復(fù)合操作。復(fù)合操作包括:迭代(反復(fù)訪問元素删掀,直到遍歷完容器中所有元素)翔冀、跳轉(zhuǎn)(根據(jù)指定順序找到當(dāng)前元素的下一個元素)以及條件運(yùn)算。這些復(fù)合操作在多線程并發(fā)地修改容器時披泪,可能會表現(xiàn)出意外的行為纤子,最經(jīng)典的便是:ConcurrentModificationException, 原因是容器迭代的過程中款票,被并發(fā)的修改了內(nèi)容控硼,這是由于早期迭代設(shè)計的時候并沒有考慮并發(fā)修改的問題。

  • 同步容器將所有對容器的狀態(tài)的訪問都串行話艾少,以實(shí)現(xiàn)他們的線程安全性卡乾。這種方法的代價是嚴(yán)重降低并發(fā)性,當(dāng)多個線程競爭容器鎖時缚够,吞吐量將嚴(yán)重降低幔妨。

    //-----------復(fù)合操作時鹦赎,并不能保證線程安全性--------------------
    final Vector<String> tickets = new Vector<>();
    for(int i = 1; i<= 1000; i++){
      tickets.add("火車票"+i);
    }
    
    // 在迭代的過程中,被后面的線程并發(fā)的修改了迭代器中的內(nèi)容误堡,就會拋出 ConcurrentModificationException
    for (Iterator iterator = tickets.iterator(); iterator.hasNext(); ) {
      String string = (String) iterator.next();
      tickets.remove(20);
    }
    
    for(int i = 1; i <=10; i ++){
      new Thread("線程"+i){
        public void run(){
          while(true){
            if(tickets.isEmpty()) break;
            System.out.println(Thread.currentThread().getName() + "---" + tickets.remove(0));
          }
        }
      }.start();
    }
    

并發(fā)容器類

  • JDK1.5 提供了多種并發(fā)容器類來改進(jìn)同步容器的性能钙姊。ConcurrentHashMap, 用來代替同步且基于散列的Map(HashTable),而且在ConcurrentHashMap 中埂伦,添加了一些常見復(fù)合操作的支持(如:“若沒有則添加煞额,替換以及有條件刪除等”)。以及 CopyOnWriteArrayList 沾谜,用于遍歷操作為主要操作的情況下代替同步的List(Voctor)膊毁。
  • JDK1.5 還增加了兩種新的容器類型: Queue 和 BlockingQueue, Queue 用來臨時保存一組等待處理的元素基跑。
    • 高性能隊(duì)列 ConcurrentLinkedQueue婚温,這是一個傳統(tǒng)的先進(jìn)先出的隊(duì)列。
    • 帶優(yōu)先級的 PriorityQueue, 這是一個非并發(fā)優(yōu)先隊(duì)列
    • BlockingQueue 擴(kuò)張了 Queue媳否, 增加拉可阻塞的插入和獲取元素等操作栅螟。如果隊(duì)列為空,那么獲取元素的操作將一直阻塞篱竭,知道隊(duì)列中出現(xiàn)一個可用的元素力图。 如果隊(duì)列已滿(對于有界隊(duì)列來說),那么插入元素的操作將一直阻塞掺逼,知道隊(duì)列中出現(xiàn)可用的空間吃媒。適用于生產(chǎn)者-消費(fèi)者設(shè)計模式。
    • 其他實(shí)現(xiàn)Queue的類:
      • LinkedBlockingQueue
      • ArrayBlockingQueue
      • PriorityBlockingQueue
      • SynchronousQueue
  • Java6 引入了 ConcurrentSkipListMap吕喘、ConcurrentSkipListSet赘那, 分別作為同步的 SortedMap 和 SortedSet 的并發(fā)替代品。例如用(synchronizedMap 包裝的TreeMap 或 TreeSet)

ConcurrentMap

  • ConcurrentMap 接口下有兩個重要的實(shí)現(xiàn):
    • ConcurrentHashMap
    • ConcurrentSkipListMap (支持并發(fā)排序功能氯质,彌補(bǔ) ConcurrentHashMap)
  • ConcurrentHashMap 內(nèi)部使用段(Segment)來表示這些不同的部分募舟,每個段其實(shí)就是一個小的HashTable,它們有自己的鎖闻察。只要多個修改操作發(fā)生在不同的段上拱礁,它們就可以并發(fā)進(jìn)行。把一個整體分成了16個段(Segment)蜓陌。也就是最高支持16個線程的并發(fā)修改操作觅彰。這也是在多線程場景時減小鎖的粒度從而降低鎖競爭的一種方案吩蔑,并且代碼中大多共享變量使用volatile關(guān)鍵字聲明钮热,目的是第一時間獲取修改的內(nèi)容。性能非常好烛芬。

Copy-On-Write容器

  • Copy-On-Write 簡稱 COW隧期,是一種用于程序設(shè)計中的優(yōu)化策略飒责。
  • JDK里的COW容器有兩種: CopyOnWriteArrayList 和 CopyOnWriteArraySet, COW容器非常有用仆潮,可以在非常多的并發(fā)場景中使用到
  • 什么是 CopyOnWrite 容器
    • CopyOnWrite 容器即 寫時復(fù)制 的容器宏蛉。通俗的理解是當(dāng)我們往一個容器添加元素的時候,不直接往當(dāng)前容器添加性置,而是先將當(dāng)前容器進(jìn)行Copy拾并,復(fù)制出一個新的容器。這樣做的好處是我們可以對CopyOnWrite 容器進(jìn)行并發(fā)的讀鹏浅,而不需要加鎖嗅义,因?yàn)楫?dāng)前容器不會添加任何元素。所以CopyOnWrite容器也是一種讀寫分離的思想隐砸,讀和寫在不同的容器中進(jìn)行之碗。
    • 當(dāng)新容器完成寫操作之后,會把原來容器的引用指向新的容器上季希。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末褪那,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子式塌,更是在濱河造成了極大的恐慌博敬,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峰尝,死亡現(xiàn)場離奇詭異冶忱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)境析,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門囚枪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人劳淆,你說我怎么就攤上這事链沼。” “怎么了沛鸵?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵括勺,是天一觀的道長。 經(jīng)常有香客問我曲掰,道長疾捍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任栏妖,我火速辦了婚禮乱豆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吊趾。我一直安慰自己宛裕,他們只是感情好瑟啃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著揩尸,像睡著了一般蛹屿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岩榆,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天错负,我揣著相機(jī)與錄音,去河邊找鬼勇边。 笑死湿颅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的粥诫。 我是一名探鬼主播油航,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼怀浆!你這毒婦竟也來了谊囚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤执赡,失蹤者是張志新(化名)和其女友劉穎镰踏,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沙合,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奠伪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了首懈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绊率。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖究履,靈堂內(nèi)的尸體忽然破棺而出滤否,到底是詐尸還是另有隱情,我是刑警寧澤最仑,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布藐俺,位于F島的核電站,受9級特大地震影響泥彤,放射性物質(zhì)發(fā)生泄漏欲芹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一吟吝、第九天 我趴在偏房一處隱蔽的房頂上張望菱父。 院中可真熱鬧,春花似錦、人聲如沸滞伟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梆奈。三九已至,卻和暖如春称开,著一層夾襖步出監(jiān)牢的瞬間亩钟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工鳖轰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留清酥,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓蕴侣,卻偏偏與公主長得像焰轻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子昆雀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

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