本身總結 :併發隊列ConcurrentLinkedQueue、阻塞隊列AraayBlockingQueue、阻塞隊列LinkedBlockingQueue 區別 和 使用場景總結

併發隊列ConcurrentLinkedQueue、阻塞隊列AraayBlockingQueue、阻塞隊列LinkedBlockingQueue 區別 和  使用場景總結

分類: Java
 
三者區別與聯繫: 聯繫,三者 都是線程安全的。區別,就是 併發  和 阻塞,前者爲併發隊列,由於採用cas算法,因此可以高併發的處理;後2者採用鎖機制,因此是阻塞的。注意點就是前者因爲採用cas算法,雖然能高併發,但cas的特色形成操做的危險性,怎麼危險性能夠去查一下cas算法(但一些多消費性的隊列仍是用的它,緣由看下邊使用場景中的說明)
 
後2者區別:聯繫,第2和第3都是阻塞隊列,都是採用鎖,都有阻塞容器Condition,經過Condition阻塞容量爲空時的取操做和容量滿時的寫操做第。區別,第2就一個整鎖,第3是2個鎖,因此第2第3的鎖機制不同,第3比第2吞吐量 大,併發性能也比第2高。
後2者的具體信息:   LinkedBlockingQueue是BlockingQueue的一種使用Link List的實現,它對頭和尾(取和添加操做)採用兩把不一樣的鎖,相對於ArrayBlockingQueue提升了吞吐量。它也是一種阻塞型的容器,適合於實現「消費者生產者」模式。

ArrayBlockingQueue是對BlockingQueue的一個數組實現,它使用一把全局的鎖並行對queue的讀寫操做,同時使用兩個Condition阻塞容量爲空時的取操做和容量滿時的寫操做。web

 正由於LinkedBlockingQueue使用兩個獨立的鎖控制數據同步,因此可使存取兩種操做並行執行,從而提升併發效率。而ArrayBlockingQueue使用一把鎖,形成在存取兩種操做爭搶一把鎖,而使得性能相對低下。LinkedBlockingQueue能夠不設置隊列容量,默認爲Integer.MAX_VALUE.其容易形成內存溢出,通常要設置其值。算法

使用場景總結:
適用阻塞隊列的好處:多線程操做共同的隊列時不須要額外的同步,另外就是隊列會自動平衡負載,即那邊(生產與消費兩邊)處理快了就會被阻塞掉,從而減小兩邊的處理速度差距,自動平衡負載這個特性就形成它能被用於多生產者隊列,由於你生成多了(隊列滿了)你就要阻塞等着,直到消費者消費使隊列不滿你才能夠繼續生產。 當許多線程共享訪問一個公共 collection 時,ConcurrentLinkedQueue 是一個恰當的選擇。
LinkedBlockingQueue 多用於任務隊列(單線程發佈任務,任務滿了就中止等待阻塞,當任務被完成消費少了又開始負載 發佈任務)
ConcurrentLinkedQueue  多用於消息隊列(多個線程發送消息,先隨便發來,不計併發的-cas特色)
 
多個生產者,對於LBQ性能還算能夠接受;可是多個消費者就不行了mainLoop須要一個timeout的機制,不然空轉,cpu會飆升的。LBQ正好提供了timeout的接口,更方便使用 若是CLQ,那麼我須要收處處理sleep
單生產者,單消費者  用 LinkedBlockingqueue  
多生產者,單消費者   用 LinkedBlockingqueue  
單生產者 ,多消費者   用 ConcurrentLinkedQueue
多生產者 ,多消費者   用 ConcurrentLinkedQueue
對上邊總結:
如消息隊列,好多client發來消息,根據client發送前後放入隊列中,先發送的就先放進來,而後因爲隊列是先進先出,是一個一個出來的,因此不涉及到線程安全問題,因此用LinkedBlockingqueue  隊列。好比還拿上邊消息隊列那個例子,因爲隊列是一個一個出來的,出來一個消息協議體就由線程池分配一個線程去處理這個消息體,這個消息體對於線程池來講談不上共享不共享的問題,即不會多個線程去搶同一個消息體去執行,因此就不須要用線程安全的隊列結構了;那假如一種狀況,隊列裏仍然是一個一個的出來,可是出來的這個元素是 線程池共享的,即你們線程都須要用到這個從隊列裏出來的這個元素,也就是多消費者消費同一個東西這種狀況,因此就要用線程安全的隊列了,即ConcurrentLinkedQueue。
相關文章
相關標籤/搜索