目錄
概述
ConcurrentHashMap
CopyOnWriteArrayList
ConcurrentLinkedQueue
BlockingQueue
ConcurrentSkipListMap
設計目的
功能特性
與其他相關類對比
適用場景
概述
JDK提供的這些容器大部分在 java.util.concurrent 包中。我們這里挑選出了一些比較有代表性的并發容器類,來感受一下JDK自帶的并發集合帶來的便利:
????????在前面幾篇也分別對這些類進行了使用場景介紹及源碼解析:
ConcurrentHashMap
ConcurrentHashMap源碼解析
CopyOnWriteArrayList
CopyOnWriteArrayList源碼解析
ConcurrentLinkedQueue
ConcurrentLinkedQueue源碼解析
BlockingQueue
阻塞隊列BlockingQueue應用及源碼解析
ConcurrentSkipListMap
????????它實現了?ConcurrentMap
?接口,提供了線程安全的有序映射
設計目的
??ConcurrentSkipListMap
?的設計目的是在多線程環境下提供一個有序的、線程安全的鍵值對映射結構。它通過跳表(Skip List)數據結構來實現高效的查找、插入和刪除操作,同時保證在多線程并發訪問時的數據一致性和線程安全性。與基于紅黑樹實現的?TreeMap
?不同,跳表結構在并發環境下具有更好的擴展性和性能。
功能特性
有序性:ConcurrentSkipListMap
?按照鍵的自然順序(如果鍵實現了?Comparable
?接口)或在構造時提供的?Comparator
?進行排序。這使得可以方便地對映射中的鍵值對進行范圍查詢、遍歷等操作。例如:
ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
map.put(3, "three");
map.put(1, "one");
map.put(2, "two");
System.out.println(map.firstKey()); // 輸出 1
System.out.println(map.lastKey()); // 輸出 3
線程安全性:ConcurrentSkipListMap
?是線程安全的,可以在多線程環境下安全地進行讀寫操作。多個線程可以同時讀取映射,而寫入操作(如插入、刪除、更新)也能在不影響其他線程讀取的情況下進行,通過內部的鎖分段技術和無鎖數據結構實現高效并發控制。
ExecutorService executorService = Executors.newFixedThreadPool(10);
ConcurrentSkipListMap<Integer, String> concurrentMap = new ConcurrentSkipListMap<>();
for (int i = 0; i < 10; i++) {executorService.submit(() -> {concurrentMap.put((int) (Math.random() * 100), "value");});
}
executorService.shutdown();
高效的操作性能:跳表結構使得?ConcurrentSkipListMap
?在查找、插入和刪除操作上具有平均?O(logn)?的時間復雜度,其中?n?是映射中的元素數量。這使得它在處理大量數據時,性能表現良好。尤其在高并發讀多寫少的場景下,性能優勢更為明顯。
范圍查詢:支持范圍查詢操作,例如可以獲取鍵在某個范圍內的子映射。例如:
ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
// 填充數據
map.put(1, "a");
map.put(3, "c");
map.put(5, "e");
ConcurrentNavigableMap<Integer, String> subMap = map.subMap(2, true, 4, true);
System.out.println(subMap); // 輸出 {3=c}
與其他相關類對比
- 與?
TreeMap
?對比:- 線程安全性:
TreeMap
?不是線程安全的,在多線程環境下需要外部同步機制來保證線程安全;而?ConcurrentSkipListMap
?本身就是線程安全的,適合多線程并發訪問。 - 性能:在高并發場景下,
ConcurrentSkipListMap
?由于采用跳表結構和更細粒度的并發控制,通常比使用外部同步的?TreeMap
?性能更好。
- 線程安全性:
- 與?
ConcurrentHashMap
?對比:- 有序性:
ConcurrentHashMap
?不保證鍵的順序,而?ConcurrentSkipListMap
?保證鍵的有序性。如果應用需要按照鍵的順序進行操作,如范圍查詢、遍歷等,ConcurrentSkipListMap
?是更好的選擇。 - 性能:
ConcurrentHashMap
?在高并發讀寫場景下具有非常高的性能,尤其是在寫操作較多的情況下。而?ConcurrentSkipListMap
?在范圍查詢和有序遍歷方面表現更好,讀操作性能也不錯,但寫操作相對?ConcurrentHashMap
?可能稍慢,因為需要維護跳表結構的有序性。
- 有序性:
適用場景
- 緩存系統:當緩存需要按照某種順序(如訪問時間、過期時間等)進行管理時,
ConcurrentSkipListMap
?可以作為緩存的底層數據結構。例如,實現一個帶有過期策略的緩存,按照過期時間排序,便于清理過期數據。 - 實時統計:在實時統計系統中,需要對數據按照某個維度(如時間戳、數值大小等)進行排序并實時更新。例如,統計一段時間內用戶的登錄次數,并按照登錄次數排序展示,
ConcurrentSkipListMap
?可以滿足這種需求。 - 索引結構:在一些需要對數據建立索引,并支持多線程并發訪問和范圍查詢的場景下,
ConcurrentSkipListMap
?可以作為索引的實現方式。例如,在數據庫的某些索引模塊中,使用?ConcurrentSkipListMap
?可以提供高效的并發訪問和范圍查找功能。