Queue與BlockingQueue

一、Queue

1.隊列繼承 Collection
2.隊列的介紹

  設計用於在處理之前保存元素的集合,除了基本的Collection操作之外,隊列還提供額外的插入,提取和檢查操作。
  這些方法的每一種都有兩種形式:如果操作失敗,則拋出一個異常;另一種返回一個特殊值( null或false ,具體取決於操作)。 
  後一種插入操作專門設計用於容量限制的Queue實現; 在大多數實現中,插入操作不能失敗。
  隊列通常但不一定是以FIFO(先進先出)方式排序元素。除了優先級隊列之外,
  根據提供的比較器對元素進行排序,決定使用自然排序還是LIFO(後進先出)進行排序的LIFO隊列(或堆棧)。 
  無論使用什麼順序,隊列的頭都是通過調用remove()或poll()刪除。在一個FIFO隊列,所有新元素插入到隊列的尾部。
  其他類型的隊列可以使用不同的佈局規則。每個Queue實現必須指定其排序屬性。 
Queue接口沒有定義阻塞隊列方法 ,阻塞隊列在併發編程中是常見的。
wait for elements to appear或space to become available的方法在BlockingQueue接口中定義,該接口擴展了此接口**
  儘管一些實現(例如LinkedList )不禁止插入null, Queue的實現通常不允許插入null元素。
即使實現允許插入null, 但是不應該在Queue插入null ,因爲null被poll方法用作特殊的返回值(當隊列爲空時,poll()返回null,容易混淆)。
Queue的實現通常不定義基於元素的方法equals和hashCode,而是使用Object繼承的版本,
因爲基於元素的等式無法很好地定義了具有相同元素但不同的排序屬性的隊列。

3.隊列的方法

offer() 與 add() :添加元素
offer方法設計用於在故障是正常的情況下,而不是發生異常的情況,例如在固定容量(“有界”)隊列中
區別:
	offer 添加元素失敗返回false
	add 添加元素失敗拋出unchecked exception
remove() 與 poll() : 刪除並返回隊列頭。
刪除隊列頭元素是隊列排序策略的一個功能,它與實現不同。
區別:
	當隊列爲空時,poll() 返回null,remove() 拋異常
element()和peek()方法返回隊列頭元素,但不會刪除頭元素。
區別 : 如果此隊列爲空,和peek() 返回 null, element() 將拋出異常。

二、BlockingQueue 阻塞隊列

1.BlockingQueue 繼承 Queue
2.BlockingQueue 的特點

i.比Queue多了在檢索元素時支持等待隊列變爲非空的操作,並且在存儲元素時等待隊列中的空間變得可用。
ii.BlockingQueue方法有四種形式,在操作時具有不同的方式,就算不會立刻滿足,但是可能在未來的某個時間點滿足:
	一個拋異常;第二個返回特殊的值(null 或false);第三個無限期的阻塞線程直到操作成功;第四個阻塞線程直到超過最大時間。
iii.不接受null元素:其實現類的方法add、put或offer使用null值會拋出NullPointerException。
iv.容量有限:在任何給定的時間它可能有一個剩餘容量,超過剩餘容量添加元素會導致阻塞。沒有任何內在容量限制的 BlockingQueue的剩餘容量爲Integer.MAX_VALUE。
v.BlockingQueue實現類被設計爲主要用於生產者 - 消費者隊列,但另外支持Collection接口。 
   例如,可以使用remove(x)從隊列中刪除任意元素。然而,這樣的操作通常不能非常有效地執行,並且僅用於偶爾使用,例如當排隊的消息被取消時。
vi.BlockingQueue實現是線程安全的。所有隊列方法使用內部鎖或其他形式的併發控制實現併發效果。然而,大多數的Collection操作addAll、containsAll、retainAll和removeAll 不一定是原子性的除非在其實現方法中特別規定。 因此有可能,例如,addAll(c)添加一些元素會失敗(拋出異常)。
vii.BlockingQueue上不支持任何類型的close或shutdown操作,close、shutdown操作表示不再添加元素。這些功能的需求和使用往往取決於實現類。例如,一個常見的策略是生產者插入結束流或者特殊的對象,消費者會使用相應地解釋。
viii.BlockingQueue可以安全地被多個生產者和多個消費者同時使用。
viii.內存一致性效果:與其他併發集合一樣,線程優先把對象放在BlockingQueue中,線程中的操作在在另一個線程中的 BlockingQueue 訪問或刪除該元素之後操作。

3.方法的區別

i.boolean add(E e)、boolean offer(E e)、put(E e) throws InterruptedException、
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException
		boolean add(E e) : 沒有可用空間返回IllegalStateException。
		boolean offer(E e) : 沒有可用空間返回null
		put(E e) throws InterruptedException : 有可用空間則將指定元素插入隊列,無可用空間則等待。 在等待時被打斷會拋 InterruptedException
		boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException: 有可用空間則將指定元素插入隊列,無可用空間則等待指定等待時間。
	ii.E take() throws InterruptedException、E poll(long timeout, TimeUnit unit) throws InterruptedException、boolean remove(Object o)
		take : 檢索並刪除此隊列的頭,有可能需要等待元素可用。 
		poll :檢索並刪除此隊列的頭,等待指定的等待時間到元素變爲可用
		remove : 從該隊列中刪除指定元素 
	iii.remainingCapacity()
		返回此隊列在理想情況下(在沒有內存或資源限制的情況下)可以不阻塞添加的元素數,如果沒有內在的限制返回Integer.MAX。
	iv.int drainTo(Collection<? super E> c) : 從該隊列中刪除所有可用的元素,並將它們添加到給定的集合c中。
	此操作比重複輪詢poll()更有效。嘗試向集合c添加元素時可能會拋出異常,可能會導致元素不在兩個集合中。 
	嘗試在隊列放自身會導致IllegalArgumentException 。 此外,如果在操作進行中修改了指定的集合,此操作的行爲是未定義的。
	v.int drainTo(Collection<? super E> c, int maxElements) : 最多從該隊列中刪除給定數量的可用元素,並將它們添加到給定的集合中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章