- 什麼情況下最好使用ArrayBlockingQueue以及何時使用LinkedBlockingQueue更好?
- 如果LinkedBlockingQueue默認容量等於MAX Integer,那麼使用它作爲具有默認容量的BlockingQueue是否真的有用?
回答
ArrayBlockingQueue
由大小在創建後永遠不會改變的數組支持。將容量設置爲Integer.MAX_VALUE
將會產生空間成本高的大陣列。 ArrayBlockingQueue
總是有界的。
LinkedBlockingQueue
動態創建節點,直到達到capacity
。這是默認的Integer.MAX_VALUE
。使用這麼大的容量在太空中沒有額外的成本。 LinkedBlockingQueue
是可選的有界。
ArrayBlockingQueue<E>
和LinkedBlockingQueue<E>
是BlockingQueue<E>
接口的常用實現。
ArrayBlockingQueue
得到array
和Queue
的支持,命令爲FIFO
。隊列頭是時間上最古老的元素,隊列的尾部是最年輕的元素。另一方面,ArrayBlockingQueue
也是固定大小的有界緩衝區LinkedBlockingQueue
是構建在鏈接節點之上的可選有界隊列。
可選的容量綁定構造函數參數用作防止過多隊列擴展的一種方式,因爲如果容量未指定,則等於Integer.MAX_VALUE
。
閱讀更多從here。
基準:http://www.javacodegeeks.com/2010/09/java-best-practices-queue-battle-and.html
我懷疑LinkedBlockingQueue會有更高的吞吐量。任何becnhmarks支持索賠? –
@EskoLuontola:你可以在這裏找到一個基準: http://www.javacodegeeks.com/2010/09/java-best-practices-queue-battle-and.html –
所以基於那個基準LinkedBlockingQueue更快產生消費者的場景,但在前兩個基準測試中,ArrayBlockingQueue稍快。不管怎麼說,Disruptor都會用這兩種方法來清理地板:https://code.google.com/p/disruptor/wiki/PerformanceResults –
添加到ArrayBlockingQueue一個元件被認爲是更快,因爲它意味着僅設置於背襯對象陣列的元素的引用,同時加入到的LinkedBlockingQueue的元件意味着創建節點和設置其item,prev和next字段。此外,當我們從LinkedBlockingQueue中移除一個元素時,被移除的Node變成垃圾,可能會影響應用程序的性能。
至於內存消耗即使在空時,ArrayBlockingQueue也始終保持一個具有全部容量的Object數組。另一方面,LinkedBlockingQueue中的一個元素是一個帶有3個對象字段的對象的節點。
這是一個很好的解釋原因的答案,但是您提到ArrayBlockingQueue應該更快,我同意與你基於你提供的原因。但Javadocs稱這一點「鏈接隊列通常比基於陣列的隊列具有更高的吞吐量,但在大多數併發應用程序中性能不太可預測。」請參閱LinkedBlockingQueue.class – spiderman
延遲和吞吐量是兩件不同的事情。ArrayBlockingQueue具有更好的延遲,因爲在數組中設置引用的速度更快,而LinkedBlockingQueue具有更好的吞吐量,因爲它對put和take使用2個差異鎖定,並且僅在邊緣條件下同步。 –
ArrayBlockingQueue:
ArrayBlockingQueue是有界的,阻塞隊列在內部存儲元件的陣列。它是有限的意味着它不能存儲無限量的元素。它可以同時存儲的元素數量有一個上限。您在實例化時間設置上限,之後不能更改。
的LinkedBlockingQueue
的的LinkedBlockingQueue保持在一個聯結構(鏈接的節點)內部的元素。如果需要,該鏈接結構可以可選地具有上限。如果沒有指定上限,則使用Integer.MAX_VALUE作爲上限。
相似度
的ArrayBlockingQueue /的LinkedBlockingQueue內部存儲元件中FIFO(先入先出)次序。隊列的頭部是隊列中最長時間的元素,隊列的尾部是隊列中最短時間的元素。
差異
- 的LinkedBlockingQueue具有putLock和takeLock用於插入和移除分別但ArrayBlockingQueue僅使用1鎖。
- ArrayBlockingQueue使用單鎖雙條件算法,LinkedBlockingQueue是「雙鎖隊列」算法的變體,它有2個鎖2條件(takeLock,putLock)。
LinkedBlockingQueue實現正在使用兩個鎖定隊列算法。因此LinkedBlockingQueue的take和put可以同時工作,但ArrayBlockingQueue並非如此。在ArrayBlockingQueue中使用單個鎖的原因是,ArrayBlockingQueue必須避免覆蓋條目,以便它需要知道起始位置和結束位置。 LinkedBlockQueue不需要知道這一點,因爲它讓GC擔心清理隊列中的節點。
- 1. 何時更喜歡LinkedBlockingQueue而不是ArrayBlockingQueue?
- 2. LinkedBlockingQueue和ConcurrentLinkedQueue有什麼區別?
- 3. 之間的〜/和的區別../
- 4. '#','%'和'$'之間的區別
- 5. {!!之間的區別!!}和{{}}
- 6. '+ ='和'= +'之間的區別?
- 7. 「。+」和「。+?」之間的區別
- 8. .eq之間的區別。和==
- 9. #。/和#之間的區別。 ./
- 10. !=和!之間的區別==
- 11. 「%〜dp0」和「。\」之間的區別?
- 12. | =和^ = css之間的區別
- 13. 之間的區別。和#
- 14. ==和case之間的區別?
- 15. 「**/* /」和「** /」之間的區別?
- 16. jQuery - '。'之間的區別和「#」
- 17. 「?1」和「?」之間的區別
- 18. `%in%`和`==`之間的區別
- 19. fmod和%之間的區別
- 20. 之間的區別:+和:+
- 21. 類區域和堆之間的區別
- 22. SPFile和PublishingPage類別之間的區別
- 23. 子類和類別之間的區別?
- 24. System.Timers.Timer Enabled = true和.Start()之間的區別Enabled = true和.Start()之間的區別
- 25. isForeground()和onExposed和onObscured之間的區別
- 26. $ .ajax()和$ .get()和$ .load()之間的區別
- 27. 和intent和setcontentview之間的區別
- 28. Java和C#和.NET之間的區別
- 29. NSthread和NStimer和NSNotifcation之間的區別?
- 30. sys.log()和console.log()和console.error()之間的區別?
對於#1的點,我想這和ArrayList vs LinkedList的原因完全一樣;) – sp00m
BlockingQueue不僅阻塞put()。當隊列爲空時,它也會阻塞take()。 –
@ sp00m,但在插入或刪除之間沒有插入隊列。所以沒有像ArrayList和LinkedList那樣的性能問題 –