JAVA並發編程有界緩衝的實現詳解_java

來源:互聯網
上載者:User

JAVA並發編程有界緩衝的實現

1、有界緩衝的基類

package cn.xf.cp.ch14;/** *  *功能:有界緩衝實現基類 *時間:下午2:20:00 *檔案:BaseBoundedBuffer.java  *@author Administrator * * @param <V> */public class BaseBoundedBuffer<V>{  private final V[] buf;  private int tail;  private int head;  private int count;    public BaseBoundedBuffer(int capacity)  {    //初始化數組    this.buf = (V[]) new Object[capacity];  }    //放入一個資料,final方法無法被重寫  protected synchronized final void doPut(V v)  {    buf[tail] = v;    if(++tail == buf.length)    {      tail = 0;    }    //插入一個方法,總量++    ++count;  }    /**   * 取出一個資料   * @return   */  protected synchronized final V doTake()  {    V v = buf[head];    buf[head] = null;    if(++head == buf.length)    {      head = 0;    }    --count;    return v;  }    //通過對count的判斷,來確定數組是否是滿的  public synchronized final boolean isFull()  {    return count == buf.length;  }    public synchronized final boolean isEmpty()  {    return count == 0;  }}

2、判定前提條件再執行操作

package cn.xf.cp.ch14;/** *  *功能:對插入和擷取元素操作進行先行檢查,然後執行操作,校正不通過不予操作 *時間:下午2:33:41 *檔案:GrumpyBoundedBuffer.java  *@author Administrator * * @param <V> */public class GrumpyBoundedBuffer<V> extends BaseBoundedBuffer<V>{  public GrumpyBoundedBuffer(int size)  {    super(size);  }    public synchronized void put(V v) throws Exception  {    //如果是滿的隊列,就無法插入新的元素    if(this.isFull())    {      throw new Exception("隊列超出");    }    this.doPut(v);  }    //同理,隊列為空白的就無法取出新的元素  public synchronized V take() throws Exception  {    if(this.isEmpty())    {      throw new Exception("隊列中無元素");    }        return this.doTake();  }}

3、通過輪詢與休眠來實現簡單的阻塞

package cn.xf.cp.ch14;/** *  *功能:通過輪詢與休眠來實現簡單的阻塞 *時間:下午2:55:54 *檔案:SleepyBoundedBuffer.java  *@author Administrator * * @param <V> */public class SleepyBoundedBuffer<V> extends BaseBoundedBuffer<V>{  //2s  private static final long SLEEP_GRANULARITY = 2000;  public SleepyBoundedBuffer(int capacity)  {    super(capacity);  }    //放入隊列的時候  public void put(V v) throws InterruptedException  {    while(true)    {      //這裡不對迴圈上鎖,不然這個鎖就無法釋放了,不對休眠上鎖,休眠上鎖,在休眠的時候別人也無法操作,永遠都不可能有元素出去      synchronized (this)      {        //如果隊列不是滿的,那麼就放入元素        if(!this.isFull())        {          this.doPut(v);          return;        }      }      //否則休眠,退出cpu佔用      Thread.sleep(SLEEP_GRANULARITY);    }  }    public V take() throws InterruptedException  {    while(true)    {      //這裡不對迴圈上鎖,不然這個鎖就無法釋放了,不對休眠上鎖,休眠上鎖,在休眠的時候別人也無法操作,永遠都不可能有新的元素進來      synchronized(this)      {        //如果數組部位空,那麼就可以取出資料        if(!this.isEmpty())        {          return this.doTake();        }        //如果隊列為空白,休眠幾秒再試      }      Thread.sleep(SLEEP_GRANULARITY);    }  }  }

4、條件隊列

package cn.xf.cp.ch14;/** *  *功能:使用條件隊列 *時間:下午3:32:04 *檔案:BoundedBuffer.java  *@author Administrator * * @param <V> */public class BoundedBuffer<V> extends BaseBoundedBuffer<V>{  public BoundedBuffer(int capacity)  {    super(capacity);  }    /**   * 放入資料元素   * @param v   * @throws InterruptedException   */  public synchronized void put(V v) throws InterruptedException  {    while(this.isFull())    {      //這裡掛起程式,會釋放鎖      this.wait();    }    //如果隊列不為滿的,那麼程式被喚醒之後從新擷取鎖    this.doPut(v);    //執行結束,喚醒其他隊列    this.notifyAll();  }    public synchronized V take() throws InterruptedException  {    while(this.isEmpty())    {      this.wait();    }    V v = this.doTake();    this.notifyAll();    return v;  }  }

感謝閱讀,希望能協助到大家,謝謝大家對本站的支援!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.