java高並發系列 - 第26篇:學會使用JUC中常見的集合,常看看!


這是java高並發系列第26篇文章。
環境:jdk1.8。

本文內容

  1. 了解JUC常見集合,學會使用
  2. ConcurrentHashMap
  3. ConcurrentSkipListMap
  4. ConcurrentSkipListSet
  5. CopyOnWriteArraySet
  6. 介紹Queue接口
  7. ConcurrentLinkedQueue
  8. CopyOnWriteArrayList
  9. 介紹Deque接口
  10. ConcurrentLinkedDeque

JUC集合框架圖

圖可以看到,JUC的集合框架也是從Map、List、Set、Queue、Collection等超級接口中繼承而來的。所以,大概可以知道JUC下的集合包含了一一些基本操作,並且變得線程安全。

Map

ConcurrentHashMap

功能和HashMap基本一致,內部使用紅黑樹實現的。

特性:

  1. 迭代結果和存入順序不一致
  2. key和value都不能為空
  3. 線程安全的

ConcurrentSkipListMap

內部使用跳表實現的,放入的元素會進行排序,排序算法支持2種方式來指定:

  1. 通過構造方法傳入一個Comparator
  2. 放入的元素實現Comparable接口

上面2種方式必選一個,如果2種都有,走規則1。

特性:

  1. 迭代結果和存入順序不一致
  2. 放入的元素會排序
  3. key和value都不能為空
  4. 線程安全的

List

CopyOnWriteArrayList

實現List的接口的,一般我們使用ArrayList、LinkedList、Vector,其中只有Vector是線程安全的,可以使用Collections靜態類的synchronizedList方法對ArrayList、LinkedList包裝為線程安全的List,不過這些方式在保證線程安全的情況下性能都不高。

CopyOnWriteArrayList是線程安全的List,內部使用數組存儲數據,集合中多線程並行操作一般存在4種情況:讀讀、讀寫、寫寫、寫讀,這個只有在寫寫操作過程中會導致其他線程阻塞,其他3種情況均不會阻塞,所以讀取的效率非常高。

可以看一下這個類的名稱:CopyOnWrite,意思是在寫入操作的時候,進行一次自我復制,換句話說,當這個List需要修改時,並不修改原有內容(這對於保證當前在讀線程的數據一致性非常重要),而是在原有存放數據的數組上產生一個副本,在副本上修改數據,修改完畢之后,用副本替換原來的數組,這樣也保證了寫操作不會影響讀。

特性:

  1. 迭代結果和存入順序一致
  2. 元素不重復
  3. 元素可以為空
  4. 線程安全的
  5. 讀讀、讀寫、寫讀3種情況不會阻塞;寫寫會阻塞
  6. 無界的

Set

ConcurrentSkipListSet

有序的Set,內部基於ConcurrentSkipListMap實現的,放入的元素會進行排序,排序算法支持2種方式來指定:

  1. 通過構造方法傳入一個Comparator
  2. 放入的元素實現Comparable接口

上面2種方式需要實現一個,如果2種都有,走規則1

特性:

  1. 迭代結果和存入順序不一致
  2. 放入的元素會排序
  3. 元素不重復
  4. 元素不能為空
  5. 線程安全的
  6. 無界的

CopyOnWriteArraySet

內部使用CopyOnWriteArrayList實現的,將所有的操作都會轉發給CopyOnWriteArrayList。

特性:

  1. 迭代結果和存入順序不一致
  2. 元素不重復
  3. 元素可以為空
  4. 線程安全的
  5. 讀讀、讀寫、寫讀 不會阻塞;寫寫會阻塞
  6. 無界的

Queue

Queue接口中的方法,我們再回顧一下:

操作類型 拋出異常 返回特殊值
插入 add(e) offer(e)
移除 remove() poll()
檢查 element() peek()

3種操作,每種操作有2個方法,不同點是隊列為空或者滿載時,調用方法是拋出異常還是返回特殊值,大家按照表格中的多看幾遍,加深記憶。

ConcurrentLinkedQueue

高效並發隊列,內部使用鏈表實現的。

特性:

  1. 線程安全的
  2. 迭代結果和存入順序一致
  3. 元素可以重復
  4. 元素不能為空
  5. 線程安全的
  6. 無界隊列

Deque

先介紹一下Deque接口,雙向隊列(Deque)是Queue的一個子接口,雙向隊列是指該隊列兩端的元素既能入隊(offer)也能出隊(poll),如果將Deque限制為只能從一端入隊和出隊,則可實現棧的數據結構。對於棧而言,有入棧(push)和出棧(pop),遵循先進后出原則。

一個線性 collection,支持在兩端插入和移除元素。名稱 deque 是“double ended queue(雙端隊列)”的縮寫,通常讀為“deck”。大多數 Deque 實現對於它們能夠包含的元素數沒有固定限制,但此接口既支持有容量限制的雙端隊列,也支持沒有固定大小限制的雙端隊列。

此接口定義在雙端隊列兩端訪問元素的方法。提供插入、移除和檢查元素的方法。每種方法都存在兩種形式:一種形式在操作失敗時拋出異常,另一種形式返回一個特殊值(nullfalse,具體取決於操作)。插入操作的后一種形式是專為使用有容量限制的 Deque 實現設計的;在大多數實現中,插入操作不能失敗。

下表總結了上述 12 種方法:

第一個元素(頭部) 第一個元素(頭部) 最后一個元素(尾部) 最后一個元素(尾部)
拋出異常 特殊值 拋出異常 特殊值
插入 addFirst(e) offerFirst(e) addLast(e) offerLast(e)
移除 removeFirst() pollFirst() removeLast() pollLast()
檢查 getFirst() peekFirst() getLast() peekLast()

此接口擴展了 Queue接口。在將雙端隊列用作隊列時,將得到 FIFO(先進先出)行為。將元素添加到雙端隊列的末尾,從雙端隊列的開頭移除元素。從 Queue 接口繼承的方法完全等效於 Deque 方法,如下表所示:

此接口擴展了 Queue接口。在將雙端隊列用作隊列時,將得到 FIFO(先進先出)行為。將元素添加到雙端隊列的末尾,從雙端隊列的開頭移除元素。從 Queue 接口繼承的方法完全等效於 Deque 方法,如下表所示:

Queue 方法 等效 Deque 方法
add(e) addLast(e)
offer(e) offerLast(e)
remove() removeFirst()
poll() pollFirst()
element() getFirst()
peek() peekFirst()

ConcurrentLinkedDeque

實現了Deque接口,內部使用鏈表實現的高效的並發雙端隊列。

特性:

  1. 線程安全的
  2. 迭代結果和存入順序一致
  3. 元素可以重復
  4. 元素不能為空
  5. 線程安全的
  6. 無界隊列

BlockingQueue

關於阻塞隊列,上一篇有詳細介紹,可以看看:掌握JUC中的阻塞隊列

java高並發系列目錄

  1. 第1天:必須知道的幾個概念
  2. 第2天:並發級別
  3. 第3天:有關並行的兩個重要定律
  4. 第4天:JMM相關的一些概念
  5. 第5天:深入理解進程和線程
  6. 第6天:線程的基本操作
  7. 第7天:volatile與Java內存模型
  8. 第8天:線程組
  9. 第9天:用戶線程和守護線程
  10. 第10天:線程安全和synchronized關鍵字
  11. 第11天:線程中斷的幾種方式
  12. 第12天JUC:ReentrantLock重入鎖
  13. 第13天:JUC中的Condition對象
  14. 第14天:JUC中的LockSupport工具類,必備技能
  15. 第15天:JUC中的Semaphore(信號量)
  16. 第16天:JUC中等待多線程完成的工具類CountDownLatch,必備技能
  17. 第17天:JUC中的循環柵欄CyclicBarrier的6種使用場景
  18. 第18天:JAVA線程池,這一篇就夠了
  19. 第19天:JUC中的Executor框架詳解1
  20. 第20天:JUC中的Executor框架詳解2
  21. 第21天:java中的CAS,你需要知道的東西
  22. 第22天:JUC底層工具類Unsafe,高手必須要了解
  23. 第23天:JUC中原子類,一篇就夠了
  24. 第24天:ThreadLocal、InheritableThreadLocal(通俗易懂)
  25. 第25天:掌握JUC中的阻塞隊列

java高並發系列連載中,總計估計會有四五十篇文章。

阿里p7一起學並發,公眾號:路人甲java,每天獲取最新文章!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM