1. 程式人生 > >java面試準備-併發包類

java面試準備-併發包類

1.ConcurrentHashMap

ConcurrentHashMap其實就是執行緒安全版本的hashMap。簡單的解釋就是通過把整個Map分為N個Segment(類似HashTable),這樣每個HashTable之間就執行緒就不會發生衝突,可以提供相同的執行緒安全,但是效率提升N倍,預設提升16倍。 
這裡寫圖片描述 
深度剖析ConcurrentHashMap 
ConcurrentHashMap原理分析

2.CopyOnWriteArrayList

  1. CopyOnWriteArrayList是執行緒安全版本的ArrayList。

  2. 什麼是CopyOnWrite容器(寫的時候複製) 
    CopyOnWrite容器即寫時複製的容器。通俗的理解是當我們往一個容器新增元素的時候,不直接往當前容器新增,而是先將當前容器進行Copy,複製出一個新的容器,然後新的容器裡新增元素,新增完元素之後,再將原容器的引用指向新的容器。這樣做的好處是我們可以對CopyOnWrite容器進行併發的讀,而不需要加鎖,因為當前容器不會新增任何元素。所以CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不同的容器。

  3. CopyOnWriteArrayList的實現原理 
    在使用CopyOnWriteArrayList之前,我們先閱讀其原始碼瞭解下它是如何實現的。 
    • 寫的時候:需要加鎖 
      以下程式碼是向CopyOnWriteArrayList中add方法的實現(向CopyOnWriteArrayList裡新增元素),可以發現在新增的時候是需要加鎖的,否則多執行緒寫的時候會Copy出N個副本出來。
    • 讀的時候:不需要加鎖 
      讀的時候不需要加鎖,如果讀的時候有多個執行緒正在向CopyOnWriteArrayList新增資料,讀還是會讀到舊的資料,因為寫的時候不會鎖住舊的CopyOnWriteArrayList。
  4. 相對於Arraylist執行緒安全,相對於vector,第一不會出現迭代器異常,第二提高了效率: 
    • 迭代器異常
      (快速失敗): 
      java中,集合在遍歷的時候,如果內部被修改了會丟擲java.util.ConcurrentModificationException錯誤。list和vector都會丟擲
    • 快速失敗 
      快速失敗是指某個執行緒在迭代vector的時候,不允許其他執行緒修改該vector的內容,這樣迭代器迭代出來的結果就會不準確,如用iterator迭代collection的時候,iterator就是另外起的一個執行緒,它去迭代collection,如果此時用collection.remove(obj)這個方法修改了collection裡面的內容的時候,就會出現ConcurrentModificationException異常,這時候該迭代器就快速失敗。 
      通俗解釋:就好像有一盤餃子,你要數數有幾個,在你還沒數完,其他人有放入(或拿走)了幾個餃子。 
      你就只能重新再數了。本來你數數就很快,但是,就有人比你手更快。
    • 讀的效率提高了 
      由於都操作沒有加鎖,所以沒有執行緒衝突;但寫操作由於加鎖,並採取了複製,所以效率更加低。所以此方法適用於讀多寫少修改少的應用。

一、阻塞佇列

  • BlockingQueue.class,阻塞佇列介面
  • BlockingDeque.class,雙端阻塞佇列介面
  • ArrayBlockingQueue.class,阻塞佇列,陣列實現
  • LinkedBlockingDeque.class,阻塞雙端佇列,連結串列實現
  • LinkedBlockingQueue.class,阻塞佇列,連結串列實現
  • DelayQueue.class,阻塞佇列,並且元素是Delay的子類,保證元素在達到一定時間後才可以取得到
  • PriorityBlockingQueue.class,優先順序阻塞佇列
  • SynchronousQueue.class,同步佇列,但是佇列長度為0,生產者放入佇列的操作會被阻塞,直到消費者過來取,所以這個佇列根本不需要空間存放元素;有點像一個獨木橋,一次只能一人通過,還不能在橋上停留

二、非阻塞佇列:

ConcurrentLinkedDeque.class,非阻塞雙端佇列,連結串列實現 
ConcurrentLinkedQueue.class,非阻塞佇列,連結串列實現

三、轉移佇列:

TransferQueue.class,轉移佇列介面,生產者要等消費者消費的佇列,生產者嘗試把元素直接轉移給消費者 
LinkedTransferQueue.class,轉移佇列的連結串列實現,它比SynchronousQueue更快

四、其它容器:

ConcurrentMap.class,併發Map的介面,定義了putIfAbsent(k,v)、remove(k,v)、replace(k,oldV,newV)、replace(k,v)這四個併發場景下特定的方法 
ConcurrentHashMap.class,併發HashMap 
ConcurrentNavigableMap.class,NavigableMap的實現類,返回最接近的一個元素 
ConcurrentSkipListMap.class,它也是NavigableMap的實現類(要求元素之間可以比較),同時它比ConcurrentHashMap更加scalable——ConcurrentHashMap並不保證它的操作時間,並且你可以自己來調整它的load factor;但是ConcurrentSkipListMap可以保證O(log n)的效能,同時不能自己來調整它的併發引數,只有你確實需要快速的遍歷操作,並且可以承受額外的插入開銷的時候,才去使用它 
ConcurrentSkipListSet.class,和上面類似,只不過map變成了set 
CopyOnWriteArrayList.class,copy-on-write模式的array list,每當需要插入元素,不在原list上操作,而是會新建立一個list,適合讀遠遠大於寫並且寫時間並苛刻的場景 
CopyOnWriteArraySet.class,和上面類似,list變成set而已