java.util.concurrent——collection

一、前言

  完成了JUC的鎖框架的分析後,現在分析JUC集合框架,之前分析過的集合框架,很大程度上都不是線程安全的,其在多線程環境下會出現很多問題,爲了保證在多線程環境下仍然能夠正確安全的訪問集合,出現了JUC下的集合框架,下面逐一進行介紹分析。

二、JUC集合框架圖

  下面給出JUC中的集合框架,之後我們會對其中的類進行詳細的分析。

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

三、具體說明

 

  3.1 Map

  1. ConcurrentHashMap

  支持獲取的完全併發和更新的所期望可調整併發的哈希表。此類遵守與 Hashtable 相同的功能規範,並且包括對應於 Hashtable 的每個方法的方法版本。不過,儘管所有操作都是線程安全的,但獲取操作不必鎖定,並且不支持以某種防止所有訪問的方式鎖定整個表。ConcurrentHashMap是通過“鎖分段”來實現的,支持高併發訪問。

  2.ConcurrentSkipListMap

  線程安全的有序的哈希表(相當於線程安全的TreeMap);映射可以根據鍵的自然順序進行排序,也可以根據創建映射時所提供的 Comparator 進行排序,具體取決於使用的構造方法。 

  3.2 List

  1. CopyOnWriteArrayList

  ArrayList 的一個線程安全的變體,其中所有可變操作(add、set 等等)都是通過對底層數組進行一次新的複製來實現的。這一般需要很大的開銷,但是當遍歷操作的數量大大超過可變操作的數量時,這種方法可能比其他替代方法更 有效。在不能或不想進行同步遍歷,但又需要從併發線程中排除衝突時,它也很有用。

  3.3 Set

  1. ConcurrentSkipListSet

  一個基於ConcurrentSkipListMap 的可縮放併發 NavigableSet 實現。set 的元素可以根據它們的自然順序進行排序,也可以根據創建 set 時所提供的 Comparator 進行排序,具體取決於使用的構造方法。

  2.CopyOnWriteArraySet

  對其所有操作使用內部CopyOnWriteArrayList的Set。即將所有操作轉發至CopyOnWriteArayList來進行操作,能夠保證線程安全。

  3.4 Queue

  1. ConcurrentLinkedQueue

  一個基於鏈接節點的無界線程安全隊列。此隊列按照 FIFO(先進先出)原則對元素進行排序。隊列的頭部 是隊列中時間最長的元素。隊列的尾部 是隊列中時間最短的元素。新的元素插入到隊列的尾部,隊列獲取操作從隊列頭部獲得元素。當多個線程共享訪問一個公共 collection 時,ConcurrentLinkedQueue 是一個恰當的選擇。此隊列不允許使用 null 元素。

  2. ConcurrentLinkedDeque

  是雙向鏈表實現的無界隊列,該隊列同時支持FIFO和FILO兩種操作方式。

3.4.1 BlockingQueue(阻塞隊列)

       3. LinkedBlockingQueue

  一個基於已鏈接節點的、範圍任意的 blocking queue。此隊列按 FIFO(先進先出)排序元素。隊列的頭部 是在隊列中時間最長的元素。隊列的尾部 是在隊列中時間最短的元素。新元素插入到隊列的尾部,並且隊列獲取操作會獲得位於隊列頭部的元素。鏈接隊列的吞吐量通常要高於基於數組的隊列,但是在大多數併發應用程序中,其可預知的性能要低。

       4. LinkedBlockingDeque

  一個基於已鏈接節點的、任選範圍的阻塞雙端隊列。

       5. ArrayBlockingQueue

  一個由數組支持的有界阻塞隊列。此隊列按 FIFO(先進先出)原則對元素進行排序。隊列的頭部 是在隊列中存在時間最長的元素。隊列的尾部 是在隊列中存在時間最短的元素。新元素插入到隊列的尾部,隊列獲取操作則是從隊列頭部開始獲得元素。

當阻塞隊列是空時,從隊列中獲取元素的操作將會被阻塞.
當阻塞隊列是滿時,往隊列中添加元素的操作將會被阻塞.

下面我們具體來看阻塞隊列常見幾種方式的方法。


  add(),remove()這組操作脾氣暴躁,有異常就拋出異常,不推薦使用;

       offer().poll()這一組操作對異常的處理是返回false或者null;

       put(),take()用於SynchronousQueue(同步隊列),即生產一個消費一個;

       offer().poll()加了時間的這一組,推薦使用,等待一段時間後。

阻塞隊列的好處

好處是我們不需要關心什麼時候需要阻塞線程,什麼時候需要喚醒線程,因爲BlockingQueue都一手給你包辦好了。 
在concurrent包 發佈以前,在多線程環境下,我們每個程序員都必須自己去控制這些細節,尤其還要兼顧效率和線程安全,而這會給我們的程序帶來不小的複雜度.

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章