LinkedBlockingQueue和ArrayBlockingQueue 對比

相同:

1、LinkedBlockingQueue和ArrayBlockingQueue都實現了BlockingQueue接口;

2、LinkedBlockingQueue和ArrayBlockingQueue都是可阻塞的隊列(內部都是使用ReentrantLock和Condition來保證生產和消費的同步;當隊列爲空,消費者線程被阻塞;當隊列裝滿,生產者線程被阻塞.)

不同:

1、隊列中的同步鎖機制不同

ArrayBlockingQueue中的鎖是沒有分離的,即生產和消費用的是同一個鎖; 使用一個ReentrantLock來保證線程安全:入列和出列前都需要獲取該鎖。

LinkedBlockingQueue中的鎖是分離的,使用兩個ReentrantLock來保證線程安全:入列前需要獲取到入列鎖(putLock),出列前需要獲取到出列鎖(takeLock),實現了入列鎖和出列鎖的分離。

2、底層實現機制不同

ArrayBlockingQueue 使用一個Object數組來存儲元素。

LinkedBlockingQueue 使用鏈表來存儲元素。

3.隊列的大小不同:

ArrayBlockingQueue 是有界隊列,且初始化時必須指定隊列的大小。

LinkedBlockingQueue 是無界隊列,在初始化的時候可以指定隊列的大小從而變成有界隊列。默認是Integer.MAX_VALUE,當入列速度大於出列速度時可能會造成內存溢出。(也可以做手工指定大小,從而成爲有界的)

4.在生產或消費時操作不同

ArrayBlockingQueue基於數組,在生產和消費的時候,是直接將枚舉對象插入或移除的,不會產生或銷燬任何額外的對象實例;

LinkedBlockingQueue基於鏈表,在生產和消費的時候,需要把枚舉對象轉換爲Node進行插入或移除,會生成一個額外的Node對象,這在長時間內需要高效併發地處理大批量數據的系統中,其對於GC的影響還是存在一定的區別。

5、併發性能

ArrayBlockingQueue中生產和消費用的是同一個鎖; 入列和出列前都需要獲取該鎖。

LinkedBlockingQueue中使用入列鎖和出列鎖的分離,故LinkedBlockingQueue的併發執行效率要高一些。

6.內存方面

ArrayBlockingQueue 用於存儲隊列元素的存儲空間是預先分配的,使用過程中內存開銷較小(無須動態申請存儲空間)

LinkedBlockingQueue 用於存儲隊列元素的存儲空間是在其使用過程中動態分配的,因此它可能會增加JVM垃圾回收的負擔。

7.吞吐量

LinkedBlockingQueue在大多數併發的場景下吞吐量比ArrayBlockingQueue高,但是性能不穩定。

Linked queues typically have higher throughput than array-based queues but less predictable performance in most concurrent applications.

這個主要針對LinkedBlockingQueue是無界的場景來說,由於無界,所以offer以及poll的吞吐量通常比ArrayBlockingQueue高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章