歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> SynchronousQueue學習筆記

SynchronousQueue學習筆記

日期:2017/3/1 9:38:03   编辑:Linux編程

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的順序傳遞資源。

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

大話設計模式(帶目錄完整版) PDF+源代碼 http://www.linuxidc.com/Linux/2014-08/105152.htm

Java中介者設計模式 http://www.linuxidc.com/Linux/2014-07/104319.htm

Java 設計模式之模板方法開發中應用 http://www.linuxidc.com/Linux/2014-07/104318.htm

設計模式之 Java 中的單例模式(Singleton) http://www.linuxidc.com/Linux/2014-06/103542.htm

跟JBPM學習設計模式 http://www.linuxidc.com/Linux/2014-06/102861.htm

Copyright © Linux教程網 All Rights Reserved