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; } }感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!