【JAVA並發編程實戰】11、有界緩存的實現,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;
}
}