java並發編程工具類JUC第四篇:LinkedBlockingQueue鏈表隊列


在之前的文章中已經為大家介紹了java並發編程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue。

LinkedBlockingQueue 隊列是BlockingQueue接口的實現類,所以它具有BlockingQueue接口的一切功能特點。LinkedBlockingQueue隊列 按照first-in-first-out (FIFO)先進先出的方式對元素進行排序。LinkeBlockingQueue 提供了兩種構造函數,一個構造函數構造一個隊列容量為固定個數的隊列,另一個無參構造函數構造一個隊列容量為Integer.MAX_VALUE的隊列.

public LinkedBlockingQueue() {
    this(Integer.MAX_VALUE);
}

public LinkedBlockingQueue(int capacity) {
    if (capacity <= 0) throw new IllegalArgumentException();
    this.capacity = capacity;
    last = head = new Node<E>(null);
}

ArrayBlockingQueue和LinkedBlockingQueue對比

ArrayBlockingQueue和LinkedBlockingQueue都是實現BlockingQueue接口,所以在使用方式上是一致的,下面我們就不介紹使用方法,而是從二者的性能及底層數據結構的實現角度進行

  • ArrayBlockingQueue插入和刪除數據,只采用了一個lock鎖,讀取和寫入操作無法並行。 所以在高並發場景下執行效率會比LinkedBlockingQueue慢一些。

  • LinkedBlockingQueue采用“two lock queue”算法變體,雙鎖(ReentrantLock):takeLock、putLock,允許讀寫並行,remove(e)和迭代器iterators需要獲取2個鎖。這樣可以降低線程由於線程無法獲取到lock而進入WAITING狀態的可能性,從而提高了線程並發執行的效率。

  • ArrayBlockingQueue底層代碼是采用數組實現的,創建的時候必須指定隊列的容量並分配存儲空間;LinkedBlockingQueue采用的是鏈表數據結構實現的,其鏈表節點的存儲空間分配是動態的,新的元素對象加入隊列分配空間,元素對象從隊列取出之后存儲空間GC,初始化時指定的是隊列的最大容量。但是使用鏈表數據結構既是LinkedBlockingQueue優勢也是它的劣勢,高並發場景下由於空間動態分配需要java JVM頻繁的進行垃圾回收。

總體來說在並發場景下,LinkedBlockingQueue的吞吐量比ArrayBlockingQueue更好。但是在java實現高性能隊列的首選是disruptor,它不是JDK自帶的。java程序員非常熟悉的Log4j2底層性能比logback和log4j有了較大的提升,究其原因就是使用了disruptor高性能隊列實現的異步日志

歡迎關注我的博客,里面有很多精品合集

  • 本文轉載注明出處(必須帶連接,不能只轉文字):字母哥博客

覺得對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創作動力! 。另外,筆者最近一段時間輸出了如下的精品內容,期待您的關注。


免責聲明!

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



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