在併發編程種,有時候須要使用線程安全的隊列,若是實現一個線程安全的隊列有兩種方式:阻塞算法、非阻塞算法。使用阻塞算法的隊列能夠用一個鎖(出入隊列用同一把鎖),或兩個鎖(入隊和出隊用不一樣的鎖),非阻塞的實現方式則能夠用循環CAS的方式實現。html
ConcurrentLinkedQueue由head節點和tail節點組成,每一個節點node由節點元素item和指向下一個節點next的引用組成。當咱們增長一個元素時,它會添加到隊列的末尾,當咱們取一個元素時,它會返回一個隊列頭部的元素。node
雖然ConcurrentLinkedQueue的性能很好,可是在調用size()方法的時候,會遍歷一遍集合,對性能損害較大,執行很慢,所以應該儘可能的減小使用這個方法,若是判斷是否爲空,最好用isEmpty()方法。算法
ConcurrentLinkedQueue不容許插入null元素,會拋出空指針異常。數據庫
ConcurrentLinkedQueue是無界的,因此使用時,必定要注意內存溢出的問題。即對併發不是很大中等的狀況下使用,否則佔用內存過多或者溢出,對程序的性能影響很大,甚至是致命的。編程
JDK7提供了7個阻塞隊列,以下。
口 ArrayBlockingqueue:ー個由數組結構組成的有界阻塞隊列。
口 LinkedBlockingqueue:一個由鏈表結構組成的有界阻塞隊列。
口 PriorityBlockingqueue:一個支持優先級排序的無界阻塞隊列。
口 Delayqueue:ー個使用優先級隊列實現的無界阻塞隊列。
口 Synchronousqueue:一個不存儲元素的阻塞隊列。
口 Linkedtransferqueue:ー個由鏈表結構組成的無界阻塞隊列。
口 LinkedblockingDeque:ー個由鏈表結構組成的雙向阻塞隊列。segmentfault
ArrayBlockingQueue extends AbstractQueue implements BlockingQueue LinkedBlockingQueue extends AbstractQueue implements BlockingQueue ConcurrentLinkedQueue extends AbstractQueue implements Queue
ConcurrentLinkedQueue基於CAS的無鎖技術,不須要在每一個操做時使用鎖,因此擴展性表現要更加優異,在常見的多線程訪問場景,通常能夠提供較高吞吐量。數組
LinkedBlockingQueue內部則是基於鎖,並提供了BlockingQueue的等待性方法。安全
ArrayBlockingQueue是初始容量固定的阻塞隊列
,咱們能夠用來做爲數據庫模塊成功競拍的隊列,好比有10個商品,那麼咱們就設定一個10大小的數組隊列。多線程
ConcurrentLinkedQueue使用的是CAS原語無鎖隊列實現,是一個異步隊列
,入隊的速度很快,出隊進行了加鎖,性能稍慢。併發
LinkedBlockingQueue也是阻塞的隊列,入隊和出隊都用了加鎖
,當隊空的時候線程會暫時阻塞。
相同:
一、LinkedBlockingQueue和ArrayBlockingQueue都實現了BlockingQueue接口;
二、LinkedBlockingQueue和ArrayBlockingQueue都是可阻塞的隊列
內部都是使用ReentrantLock和Condition來保證生產和消費的同步;
當隊列爲空,消費者線程被阻塞;當隊列裝滿,生產者線程被阻塞;
使用Condition的方法來同步和通訊:await()和signal()
不一樣:
一、由上圖能夠看出,他們的鎖機制不一樣
LinkedBlockingQueue中的鎖是分離的,生產者的鎖PutLock,消費者的鎖takeLock
而ArrayBlockingQueue生產者和消費者使用的是同一把鎖;
二、他們的底層實現機制也不一樣
LinkedBlockingQueue內部維護的是一個鏈表結構
在生產和消費的時候,須要建立Node對象進行插入或移除,大批量數據的系統中,其對於GC的壓力會比較大
而ArrayBlockingQueue內部維護了一個數組
在生產和消費的時候,是直接將枚舉對象插入或移除的,不會產生或銷燬任何額外的對象實例
三、構造時候的區別
LinkedBlockingQueue有默認的容量大小爲:Integer.MAX_VALUE,固然也能夠傳入指定的容量大小
ArrayBlockingQueue在初始化的時候,必須傳入一個容量大小的值
看其提供的構造方法就能知道
四、執行clear()方法
LinkedBlockingQueue執行clear方法時,會加上兩把鎖
五、統計元素的個數
LinkedBlockingQueue中使用了一個AtomicInteger對象來統計元素的個數
ArrayBlockingQueue則使用int類型來統計元素
https://www.jb51.net/article/90899.htm(好)
https://blog.csdn.net/jameshadoop/article/details/52729796