Java-SynchronousQueue 阻塞隊列小記

來源:互聯網
上載者:User

標籤:java   synchronousqueue   阻塞隊列   同步隊列   

在BlockingQueue的子類中有一個SynchronousQueue(同步隊列)比較少見,現在做一個簡單的介紹,並附加一個簡單的例子。SynchronousQueue --JDK1.6介紹:
public class SynchronousQueue<E>
   
extends AbstractQueue<E>
implements BlockingQueue<E>, Serializable

一種阻塞隊列,其中每個插入操作必須等待另一個線程的對應移除操作 ,反之亦然。同步隊列沒有任何內部容量,甚至連一個隊列的容量都沒有。不能在同步隊列上進行 peek,因為僅在試圖要移除元素時,該元素才存在;除非另一個線程試圖移除某個元素,否則也不能(使用任何方法)插入元素;也不能迭代隊列,因為其中沒有元素可用於迭代。隊列的 是嘗試添加到隊列中的首個已排隊插入線程的元素;如果沒有這樣的已排隊線程,則沒有可用於移除的元素並且 poll() 將會返回 null。對於其他 Collection 方法(例如 contains),SynchronousQueue 作為一個空 collection。此隊列不允許 null 元素。

同步隊列類似於 CSP 和 Ada 中使用的 rendezvous 通道。它非常適合於傳遞性設計,在這種設計中,在一個線程中啟動並執行對象要將某些資訊、事件或任務傳遞給在另一個線程中啟動並執行對象,它就必須與該對象同步。

對於正在等待的生產者和使用者線程而言,此類支援可選的公平排序策略。預設情況下不保證這種排序。但是,使用公平設定為 true 所構造的隊列可保證線程以 FIFO 的順序進行訪問。公平通常會降低輸送量,但是可以減小可變性並避免得不到服務。 

此類及其迭代器實現 Collection 和 Iterator 介面的所有可選 方法。

簡介及注意點

SynchronousQueue同步隊列(哈哈不知準確否)繼承了BlockingQueue<E>介面,功能類似於:一直等待,來一個及時處理一個,但不能同事處理兩個。比如queue.take()方法會阻塞,一直queue.offer(element)插入一個元素,二插入的元素馬上就別queue.take()處理掉。所以它沒有容納元素的能力,isEmpty方法總是返回true,但是給人的感覺像是可以臨時容納一個元素。

另外在建立SynchronousQueue時可以傳遞一個boolean參數來指定它是否是訪問它的線程按遵守FIFO順序處理,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。程式碼範例:

import java.util.Random;import java.util.concurrent.SynchronousQueue;import java.util.concurrent.TimeUnit;/** * 下面使用SynchronousQueue類比: * 最多隻有一個產品的生產者-消費者模型 *  * 消費者線程們 逐個請求消費產品 * 生產者線程們 逐個生產產品。 *  * @author maguowei01 *  */public class SynchronousQueueTest {public static void main(String[] args) {                //true保證生產或消費者線程以FIFO的順序訪問。SynchronousQueue<Integer> queue = new SynchronousQueue<Integer>(true);for (int i = 0; i < 3; ++i) {new Customer(queue).start();}for (int i = 0; i < 3; ++i) {new Product(queue).start();}}static class Product extends Thread {SynchronousQueue<Integer> queue;public Product(SynchronousQueue<Integer> queue) {this.queue = queue;}@Overridepublic void run() {while (true) {int rand = new Random().nextInt(1000);System.out.println("Thread Id:" + getId() + "  生產了一個產品:" + rand);System.out.println("Thread Id:" + getId() + " 等待兩秒後運送出去...");try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}/* * offer()往queue裡放一個element後立即返回,如果碰巧這個element被另一個thread取走了, * offer方法返回true,認為offer成功;否則返回false。 * 也就是說offer不一定真正的插入的隊列中,肯定沒成功丟失了 */// queue.offer(rand);  //注意offer與put方法的區別try {/*  * put()往queue放進去一個element以後就一直wait直到有其他thread進來把這個element取走。 */queue.put(rand);} catch (InterruptedException e) {e.printStackTrace();}}}}static class Customer extends Thread {SynchronousQueue<Integer> queue;public Customer(SynchronousQueue<Integer> queue) {this.queue = queue;}@Overridepublic void run() {while (true) {try {// 線程運行到queue.take()阻塞,直到Product生產一個產品queue.offer。System.out.println("Thread Id:" + getId() + " 消費了一個產品:" + queue.take());} catch (InterruptedException e) {e.printStackTrace();}System.out.println("------------------------------------------");}}}}


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.