SynchronousQueue

http://wsmajunfeng.iteye.com/blog/1629352/

SynchronousQueue是這樣一種阻塞隊列,其中每個 put 必須等待一個 take,反之亦然。同步隊列沒有任何內部容量,甚至連一個隊列的容量都沒有。 
     不能在同步隊列上進行 peek,因爲僅在試圖要取得元素時,該元素才存在; 
     除非另一個線程試圖移除某個元素,否則也不能(使用任何方法)添加元素;也不能迭代隊列,因爲其中沒有元素可用於迭代。隊列的頭是嘗試添加到隊列中的首個已排隊線程元素; 如果沒有已排隊線程,則不添加元素並且頭爲 null。 
     對於其他 Collection 方法(例如 contains),SynchronousQueue 作爲一個空集合。此隊列不允許 null 元素。
    它非常適合於傳遞性設計,在這種設計中,在一個線程中運行的對象要將某些信息、 
事件或任務傳遞給在另一個線程中運行的對象,它就必須與該對象同步。 
    對於正在等待的生產者和使用者線程而言,此類支持可選的公平排序策略。默認情況下不保證這種排序。 
    但是,使用公平設置爲 true 所構造的隊列可保證線程以 FIFO 的順序進行訪問。 公平通常會降低吞吐量,但是可以減小可變性並避免得不到服務。 
    注意1:它一種阻塞隊列,其中每個 put 必須等待一個 take,反之亦然。同步隊列沒有任何內部容量,甚至連一個隊列的容量都沒有。 
    注意2:它是線程安全的,是阻塞的。 
    注意3:不允許使用 null 元素。 
    注意4:公平排序策略是指調用put的線程之間,或take的線程之間。公平排序策略可以查考ArrayBlockingQueue中的公平策略。 
    注意5:SynchronousQueue的以下方法: 
    * iterator() 永遠返回空,因爲裏面沒東西。 
    * peek() 永遠返回null。 
    * put() 往queue放進去一個element以後就一直wait直到有其他thread進來把這個element取走。 
    * offer() 往queue裏放一個element後立即返回,如果碰巧這個element被另一個thread取走了,offer方法返回true,認爲offer成功;否則返回false。 
    * offer(2000, TimeUnit.SECONDS) 往queue裏放一個element但是等待指定的時間後才返回,返回的邏輯和offer()方法一樣。 
    * take() 取出並且remove掉queue裏的element(認爲是在queue裏的。。。),取不到東西他會一直等。 
    * poll() 取出並且remove掉queue裏的element(認爲是在queue裏的。。。),只有到碰巧另外一個線程正在往queue裏offer數據或者put數據的時候,該方法纔會取到東西。否則立即返回null。 
    * poll(2000, TimeUnit.SECONDS) 等待指定的時間然後取出並且remove掉queue裏的element,其實就是再等其他的thread來往裏塞。 
    * isEmpty()永遠是true。 
    * remainingCapacity() 永遠是0。 
    * remove()和removeAll() 永遠是false。 

 

 

 

這是一個很有意思的阻塞隊列,其中每個插入操作必須等待另一個線程的移除操作,同樣任何一個移除操作都等待另一個線程的插入操作。因此此隊列內部其 實沒有任何一個元素,或者說容量是0,嚴格說並不是一種容器。由於隊列沒有容量,因此不能調用peek操作,因爲只有移除元素時纔有元素。

一個沒有容量的併發隊列有什麼用了?或者說存在的意義是什麼?

SynchronousQueue 的實現非常複雜,當然瞭如果真要去分析還是能夠得到一些經驗的,但是前面分析了過多的結構後,發現越來越陷於數據結構與算法裏面了。我的初衷是通過研究並 發實現的原理來更好的利用併發來最大限度的利用可用資源。所以在後面的章節中儘可能的少研究數據結構和算法,但是爲了弄清楚裏面的原理,必不可免的會涉及 到一些這方面的知識,希望後面能夠適可而止。

再回到話題。SynchronousQueue 內部沒有容量,但是由於一個插入操作總是對應一個移除操作,反過來同樣需要滿足。那麼一個元素就不會再SynchronousQueue 裏面長時間停留,一旦有了插入線程和移除線程,元素很快就從插入線程移交給移除線程。也就是說這更像是一種信道(管道),資源從一個方向快速傳遞到另一方 向。

需要特別說明的是,儘管元素在SynchronousQueue 內部不會“停留”,但是並不意味之SynchronousQueue 內部沒有隊列。實際上SynchronousQueue 維護者線程隊列,也就是插入線程或者移除線程在不同時存在的時候就會有線程隊列。既然有隊列,同樣就有公平性和非公平性特性,公平性保證正在等待的插入線 程或者移除線程以FIFO的順序傳遞資源。

顯然這是一種快速傳遞元素的方式,也就是說在這種情況下元素總是以最快的方式從插入着(生產者)傳遞給移除着(消費者),這在多任務隊列中是最快處理任務的方式。在線程池的相關章節中還會更多的提到此特性。


發佈了132 篇原創文章 · 獲贊 38 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章