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; } }
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(); } }
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); } } }
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; } }