鮑里斯蜘蛛已經列出了ArrayBlockingQueue
和LinkedBlockingQueue
之間最明顯的區別 - 前者總是有界的,而後者可能是無界的。
因此,如果您需要無限制的阻塞隊列,LinkedBlockingQueue
或LinkedTransferQueue
用作BlockingQueue
是java.util.concurrent
工具箱的最佳投注。
但是讓我們假設你需要一個有界的阻塞隊列。最後,你應該選擇一個基於廣泛的實驗和實際工作負載模擬的實現。 然而,這裏有一些注意事項,可以幫助您與您所選擇或解釋從實驗結果:
ArrayBlockingQueue
可以用配置來創建(開/關)調度的公平性的政策。如果你需要公平性或者想要避免生產者/消費者的飢餓,這是非常好的,但是這會導致你的吞吐量。
ArrayBlockingQueue
預先分配其後備數組,因此它在使用過程中不會分配節點,但它會立即使用相當可觀的內存塊,如果內存出現碎片,這可能會造成問題。
ArrayBlockingQueue
應在性能較小的變化,因爲它有運動部件少的整體,它採用了簡單和不太複雜的單鎖算法,它在使用過程中不產生節點,它的緩存行爲應該是相當一致的。
LinkedBlockingQueue
應該有更好的吞吐量,因爲它使用單獨的頭部和尾部的鎖。
LinkedBlockingQueue
不預先分配的節點,這意味着它的內存佔用量將大致匹配它的大小,但它也意味着它會招致分配和節點釋放一些工作。
LinkedBlockingQueue
可能會有更糟糕的緩存行爲,這可能會影響其自身的性能,但也會由於虛假共享而影響其他組件的性能。
根據您的使用情況和多少你關心性能,你可能也想看看外面的java.util.concurrent
,並考慮Disruptor(一個非常快,但有些專業界無阻塞環形緩衝區)或JCTools (根據生產者和消費者的數量,各種有界限或無界限的不同保障隊列)。
好的答案!我同意你提到的內容,我還想強調(再一次)ArrayBlockingQueue由一個數組支持的事實,該數組的大小在創建之後永遠不會改變。將容量設置爲Integer.MAX_VALUE會創建一個空間成本高的大陣列。 ArrayBlockingQueue總是有界的。 LinkedBlockingQueue動態創建節點,直到達到容量。這是默認情況下的Integer.MAX_VALUE。使用這麼大的容量在太空中沒有額外的成本。 LinkedBlockingQueue是可選的有界。 –