ConcurrentLinkedQueue和LinkedBlockingQueue區別


原創轉載請注明出處:https://www.cnblogs.com/agilestyle/p/11394436.html

 

線程安全隊列類圖


兩者的區別在於

  • ConcurrentLinkedQueue基於CAS的無鎖技術,不需要在每個操作時使用鎖,所以擴展性表現要更加優異,在常見的多線程訪問場景,一般可以提供較高吞吐量。
  • LinkedBlockingQueue內部則是基於鎖,並提供了BlockingQueue的等待性方法。

BlockingQueue基本都是基於鎖實現,比如典型的LinkedBlockingQueue


 

有界隊列

  • ArrayBlockingQueue是最典型的的有界隊列,其內部以final的數組保存數據,數組的大小就決定了隊列的邊界,所以我們在創建ArrayBlockingQueue時,都要指定容量,如
public ArrayBlockingQueue(int capacity, boolean fair) 
  • LinkedBlockingQueue,容易被誤解為無邊界,但其實其行為和內部代碼都是基於有界的邏輯實現的,只不過如果我們沒有在創建隊列時就指定容量,那么其容量限制就自動被設置為Integer.MAX_VALUE,成為了無界隊列。
  • SynchronousQueue,這是一個非常奇葩的隊列實現,每個刪除操作都要等待插入操作,反之每個插入操作也都要等待刪除動作。那么這個隊列的容量是多少呢?是1嗎?其實不是的,其內部容量是0。

 

無界隊列

  • PriorityBlockingQueue是無邊界的優先隊列,雖然嚴格意義上來講,其大小總歸是要受系統資源影響。
  • DelayedQueue和LinkedTransferQueue同樣是無邊界的隊列。對於無邊界的隊列,有一個自然的結果,就是put操作永遠也不會發生其他BlockingQueue的那種等待情況。

 

有界隊列使用場景

以LinkedBlockingQueue、ArrayBlockingQueue和SynchronousQueue為例,根據需求可以從很多方面考量:

  • 考慮應用場景中對隊列邊界的要求。ArrayBlockingQueue是有明確的容量限制的,而LinkedBlockingQueue則取決於我們是否在創建時指定,SynchronousQueue則干脆不能緩存任何元素。
  • 從空間利用角度,數組結構的ArrayBlockingQueue要比LinkedBlockingQueue緊湊,因為其不需要創建所謂節點,但是其初始分配階段就需要一段連續的空間,所以初始內存需求更大。
  • 通用場景中,LinkedBlockingQueue的吞吐量一般優於ArrayBlockingQueue,因為它實現了更加細粒度的鎖操作。
  • ArrayBlockingQueue實現比較簡單,性能更好預測,屬於表現穩定的“選手”。
  • 如果需要實現的是兩個線程之間接力性(handoff)的場景,可能會選擇CountDownLatch,但是SynchronousQueue也是完美符合這種場景的,而且線程間協調和數據傳輸統一起來,代碼更加規范。
  • 可能令人意外的是,很多時候SynchronousQueue的性能表現,往往大大超過其他實現,尤其是在隊列元素較小的場景。

 

Reference

https://time.geekbang.org/column/article/9588


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM