2012-08-06 36 views
5

據我所知,鏈表和數組可以無限增長或我錯了嗎?但是,當我通過documentation in the Executor Service我看到這個:爲什麼ArrayBlockingQueue被稱爲有界隊列而LinkedBlockingQueue被稱爲無界阻塞隊列?

無界隊列。如果所有corePoolSize線程都忙,則使用無界隊列(例如 LinkedBlockingQueue沒有預定義容量)將導致新的 任務在隊列中等待。 因此,不會創建corePoolSize線程。 (和maximumPoolSize的 價值,因此沒有任何影響。)

如此做Unbounded Queue屬性變化的時候,LinkedBlockingQueue有一個定義的能力呢?

而這種書面ArrayBlockingQueue

界隊列。有限隊列(例如,ArrayBlockingQueue) 有助於防止與有限的最大池尺寸一起使用時的資源耗盡,但可能更難以調整和控制。隊列 大小和最大池大小可以彼此交換:使用大隊列和小池可最大限度地減少CPU使用率,OS資源和上下文切換開銷,但會導致人爲地降低吞吐量。如果任務頻繁阻塞(例如,如果它們是I/O ),則系統可能會計劃時間以獲得比您允許的更多的線程數量的 。使用小隊列通常需要更大的池大小,這會使CPU更繁忙,但可能會遇到不可接受的調度開銷,這也會降低吞吐量。

回答

7

爲什麼你認爲ArrayBlockingQueue可以無邊界增長? From own documentation

這是一個經典的「有界緩衝區」,其中一個固定大小的數組包含由生產者插入並由消費者提取的元素。一旦創建,容量就不能增加。嘗試將元素放入完整隊列將導致操作阻塞;嘗試從一個空隊列中取一個元素也會同樣阻塞。

換句話說,一旦它滿了,它已滿 - 它不會增長。

你是否有機會與ArrayList混淆 - 哪個也支持數組,但是會根據需要擴展它?

因此,當LinkedBlockingQueue具有定義的容量時,Unbounded Queue屬性是否會更改?

是的,因此爲什麼在Javadocs中將其描述爲「可選 - 有界」。此外,文檔聲明(重點是我的):

可選的容量綁定構造函數參數用作防止過多隊列擴展的一種方法。如果未指定,容量等於Integer.MAX_VALUE。除非這會使隊列超出容量,否則鏈接的節點會在每次插入時動態創建

+0

@Andrej是我混淆ArrayList Array。謝謝澄清。順便說一句,當ArrayList由不能增長的底層數組支持時,ArrayList是如何增長的? – Geek 2012-08-06 14:54:59

+4

當需要調整大小時,ArrayList會分配一個新的更大的數組,並將所有元素複製到該新數組中。 – 2012-08-06 14:59:09

2

據我知道,這兩個鏈表和數組沒有界限可能會增大或我錯了

鏈表的大小不受限制。一個數組具有固定的大小。 ArrayList封裝了一個數組,並在需要更大的數組時將其替換。

如此做無界隊列屬性發生變化時的LinkedBlockingQueue具有確定的容量

當的LinkedBlockingQueue有一個最大容量,它是有界的,但它不使用這種方式默認。

+1

「當ArrayList需要更大的數組時,包裝數組將替換它。」你可以在ArrayList的ensureCapacity方法中看到這個。 – 2012-08-06 14:59:37

3

從documentataion爲ArrayBlockingQueue

甲界阻塞隊列由數組支持。該隊列命令元素FIFO(先進先出)。隊列頭是最長時間在隊列中的元素。隊列的尾部是已經在隊列上的最短時間的元素。新元素插入到隊列尾部,隊列檢索操作獲取隊列頭部的元素。

如果您注意到ArrayBlockingQueue的所有構造函數都具有一個容量,因爲此類設計爲有界的。做出這個選擇是因爲如果你想要一個併發隊列,你可能不需要調整一個ArrayList的開銷。因此,如果你想要一個無界隊列LinkedBlockingQueue是一個更好的選擇,因爲它不涉及這個開銷。

2

javadoc for LinkedBlockingQueue說:

基於鏈接節點的任意的blocking隊列[...]

可選的容量範圍構造參數作爲一種方法來 防止過度隊列擴張。 。如果未指定,容量爲 等於Integer.MAX_VALUE。

javadoc of ArrayBlockingQueue說:

甲界阻塞隊列由數組支持[...]

這是一個典型的「有界緩衝」,其中一個固定大小的數組。持有由生產者插入並由消費者提取的元素 。一旦創建 ,容量不能增加

所以,鏈接的阻塞隊列可以是有界的無界歐,而的ArrayBlockingQueue總是有界的。

0

其他答案很正確!我提供了另一種解釋方式。 好吧,我也對「未綁定和綁定」一詞感到困惑。你可以看看源代碼自爆。

/** The queued items */ 
final Object[] items; 

/** items index for next take, poll, peek or remove */ 
int takeIndex; 

/** items index for next put, offer, or add */ 
int putIndex; 

/** Number of elements in the queue */ 
int count; 

從源代碼,我們可以看到陣列是最終,所以我們不能調整該陣列。如果使用LinkedBlockingQueue,我們總是可以添加更多元素......並且在源代碼中,下一個引用不是最終的。注意,從理論上講,LinkedBlockingQueue不是無界的。因爲它只能存儲MAX_INTEGER減8個元素。從javadoc中,無界隊列是PriorityBlockingQueue。但PriorityBlockingQueue也只能存儲MAX_INTEGER -8個元素。所以我認爲沒有完美無邊的隊列...