同步容器經過synchronized關鍵字修飾容器保證同一時刻內只有一個線程在使用容器,從而使得容器線程安全。synchronized的意思是同步,它體如今將多線程變爲串行等待執行。(但注意一點,複合操做不能保證線程安全。舉例:A線程第一步獲取尾節點,第二步將尾結點的值加1,但在A線程執行完第一步的時候,B線程刪除了尾節點,在A線程執行第二步的時候就會報空指針)html
併發容器指的是容許多線程同時使用容器,而且保證線程安全。而爲了達到儘量提升併發,Java併發工具包中採用了多種優化方式來提升併發容器的執行效率,核心的就是:鎖、CAS(無鎖)、COW(讀寫分離)、分段鎖。算法
Vector和ArrayList同樣實現了List接口,其對於數組的各類操做和ArrayList同樣,區別在於Vertor在可能出現線程不安全的全部方法都用synchronized進行了修飾。數組
Stack是Vertor的子類,Stack實現的是先進後出的棧。在出棧入棧等操做都進行了synchronized修飾。安全
HashTable實現了Map接口,它實現的功能HashMap基本一致(HashTable不可存null,而HashMap的鍵和值均可以存null)。區別在於HashTable使用了synchronized修飾了方法。數據結構
其實以上三個容器都是Collections經過代理模式對本來的操做加上了synchronized同步。而synchronized的同步粒度太大,致使在多線程處理的效率很低。因此在JDK1.5的時候推出了併發包下的併發容器,來應對多線程下容器處理效率低的問題。多線程
CopyOnWriteArrayList至關於實現了線程安全的ArrayList,它的機制是在對容器有寫入操做時,copy出一份副本數組,完成操做後將副本數組引用賦值給容器。底層是經過ReentrantLock來保證同步。但它經過犧牲容器的一致性來換取容器的高併發效率(在copy期間讀到的是舊數據)。因此不能在須要強一致性的場景下使用。併發
CopyOnWriteArraySet和CopyOnWriteArrayList原理同樣,它是實現了CopyOnWrite機制的Set集合。高併發
ConcurrentHashMap至關於實現了線程安全的HashMap。其中的key是無序的,而且key和value都不能爲null。在JDK8以前,ConcurrentHashMap採用了分段鎖機制來提升併發效率,只有在操做同一分段的鍵值對時才須要加鎖。到了JDK8以後,摒棄了鎖分段機制,改成利用CAS算法。工具
ConcurrentSkipListMap至關於實現了線程安全的TreeMap。其中的key是有序的,而且key和value都不能爲null。它採用的跳躍表的機制來替代紅黑樹。爲何不繼續使用紅黑樹呢?由於紅黑樹在插入或刪除節點的時候須要旋轉調整,致使須要控制的粒度較大。而跳躍表使用的是鏈表,利用無鎖CAS機制實現高併發線程安全。優化
ConcurrentSkipListSet和ConcurrentSkipListMap原理同樣,它是實現了高併發線程安全的TreeSet。
ArrayBlockingQueue是採用數組實現的有界阻塞線程安全隊列。若是向已滿的隊列繼續塞入元素,將致使當前的線程阻塞。若是向空隊列獲取元素,那麼將致使當前線程阻塞。採用ReentrantLock來保證在併發狀況下的線程安全。
LinkedBlockingQueue是一個基於單向鏈表的、範圍任意的(實際上是有界的)、FIFO 阻塞隊列。訪問與移除操做是在隊頭進行,添加操做是在隊尾進行,並分別使用不一樣的鎖進行保護,只有在可能涉及多個節點的操做才同時對兩個鎖進行加鎖。
PriorityBlockingQueue是一個支持優先級的無界阻塞隊列。默認狀況下元素採用天然順序升序排列。也能夠自定義類實現compareTo()方法來指定元素排序規則,
DelayQueue是一個內部使用優先級隊列實現的無界阻塞隊列。同時元素節點數據須要等待多久以後纔可被訪問。取數據隊列爲空時等待,有數據但延遲時間未到時超時等待。
SynchronousQueue沒有容量,是一個不存儲元素的阻塞隊列,會直接將元素交給消費者,必須等隊列中的添加元素被消費後才能繼續添加新的元素。至關於一條容量爲1的傳送帶。
LinkedTransferQueue是一個有鏈表組成的無界傳輸阻塞隊列。它集合了ConcurrentLinkedQueue、SynchronousQueue、LinkedBlockingQueue等優勢。具體機制較爲複雜。
LinkedBlockingDeque是一個由鏈表結構組成的雙向阻塞隊列。所謂雙向隊列指的是能夠從隊列的兩端插入和移出元素。
ConcurrentLinkedQueue是線程安全的無界非阻塞隊列,其底層數據結構是使用單向鏈表實現,入隊和出隊操做是使用咱們常常提到的CAS來保證線程安全。