一、同步類容器的種類
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方法