併發編程:同步類容器、併發類容器

一、同步類容器的種類

1、Vector

Vector實現了List接口,Vector實際上就是一個數組,和ArrayList類似,但是Vector中的方法都是synchronized方法,即進行了同步措施。

2、HashTable

HashTable實現了Map接口,它和HashMap很相似,但是HashTable進行了同步處理,而HashMap沒有。

二、同步類容器的缺陷

在對同步類容器進行迭代修改是,會拋出ConcurrentModificationException異常。

參考鏈接:https://www.cnblogs.com/dolphin0520/p/3933404.html

三、併發類容器

1、ConcurrentHashMap

ConcurrentMap接口有兩個重要實現:ConcurrentHashMap和ConcurrentSkipListMap(支持併發排序功能,彌補了ConcurrentHashMap)。

ConcurrentHashMap內部使用段(Segment)來表示不同的部分,每一個段其實是一個小的HashTable,它們有自己的鎖。只要修改操作發生在不同的段上,就可以實現併發操作。一個整體分成16個段,最高支持16個線程的併發修改操作。通過減少鎖的粒度從而降低鎖競爭。代碼中大量使用volatile關鍵字聲明,可以第一時間獲取修改內容,性能很好。

2、Copy-On-Write簡稱COW

JDK中COW容器有兩種:CopyOnWriteArrayList和CopyOnWriteArraySet。

什麼是CopyOnWrite容器?

當往容器中添加元素的時候,不直接向當前容器中添加元素,而是複製一份一模一樣的當前容器,在新的容器裏面添加元素,添加完元素後,將原容器的引用指向新的容器。這樣做的好處是可以對CopyOnWrite容器進行併發的讀,而不需要加鎖。CopyOnWrite容器是一種讀寫分離的思想。     該容器適合於讀多寫少的場景。

非阻塞隊列

1、ConcurrentLinkedQueue

ConcurrentLinkedQueue是一種適用於高併發場景下的隊列,通過無鎖的方式,實現了高併發狀態下的高性能,通常ConcurrentLinkedQueue性能好於BlockingQueue。它是一個基於鏈接節點的無界線程安全隊列,遵循先進先出的原則,該隊列不允許null元素。

ConcurrentLinkedQueue重要方法:

add()和offer()都是加入元素的方法(在ConcurrentLinkedQueue,這兩個方法沒區別)。

poll()和peek()都是取頭元素結點,區別在於poll()會刪除元素,peek()不會刪除元素。

阻塞隊列

1、ArrayBlockingQueue

基於數組實現的阻塞隊列,在ArrayBlockingQueue內部維護着一個定長的數組,來緩存隊列中的數據對象,內部沒有實現讀寫分離,也就意味着生產和消費不能完全並行,長度是需要定義的,可以指定先進先出或先進後出,也叫有界隊列。

2、LinkedBlockingQueue

基於鏈表的阻塞隊列,LinkedBlockingQueue之所以能夠高效的處理併發數據,是因爲其內部實現採用分離鎖(讀寫分離兩個鎖),從而實現生產者和消費者完全並行。它是一種無界隊列。

3、SynchronousQueue

沒有緩衝的隊列,生產者生產的數據會被消費者直接消費。

4、PriorityBlockingQueue(調用take方法的時候會對隊列中的元素進行排序)

基於優先級的阻塞隊列(優先級的判斷通過構造函數傳入的Compator對象來決定,傳入隊列的對象必須實現Comparable接口),實現PriorityBlockingQueue時,內部控制線程同步的鎖採用的是公平鎖,它是一種無界隊列。

5、DelayQueue

帶有延遲時間的隊列,其中的元素只有當其指定的延遲時間到了,才能夠從隊列中獲取元素。DelayQueue中的元素必須實現Delayed接口,DelayQueue是一個沒有大小限制的隊列,應用場景很多,比如對緩存超時的數據進行移除、任務超時處理、空閒連接的關閉等等。

6、在阻塞隊列中put、offer、add三種方法的區別

offer:如果隊列滿了直接返回false

put:如果隊列滿了會阻塞,直到收到通知

add:1、如果隊列滿了直接返回(不阻塞)直接報錯 2、內部實際上調用的是offer方法

 

 

 

 

 

 

 

 

 

 

 

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