java多线程之:SynchronousQueue队列
轉載自??java多線程之:SynchronousQueue隊列
?
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的順序傳遞資源。
顯然這是一種快速傳遞元素的方式,也就是說在這種情況下元素總是以最快的方式從插入著(生產者)傳遞給移除著(消費者),這在多任務隊列中是最快處理任務的方式。在線程池的相關章節中還會更多的提到此特性。
總結
以上是生活随笔為你收集整理的java多线程之:SynchronousQueue队列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ps3d电脑配置(3d 电脑配置)
- 下一篇: 网络主机。al-很好的定价和对客户服务的