相同:
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高。