JAVA并发编程有界缓存的实现详解
JAVA并发编程有界缓存的实现
1、有界缓存的基类
packagecn.xf.cp.ch14;
/**
*
*功能:有界缓存实现基类
*时间:下午2:20:00
*文件:BaseBoundedBuffer.java
*@authorAdministrator
*
*@param<V>
*/
publicclassBaseBoundedBuffer<V>
{
privatefinalV[]buf;
privateinttail;
privateinthead;
privateintcount;
publicBaseBoundedBuffer(intcapacity)
{
//初始化数组
this.buf=(V[])newObject[capacity];
}
//放入一个数据,final方法无法被重写
protectedsynchronizedfinalvoiddoPut(Vv)
{
buf[tail]=v;
if(++tail==buf.length)
{
tail=0;
}
//插入一个方法,总量++
++count;
}
/**
*取出一个数据
*@return
*/
protectedsynchronizedfinalVdoTake()
{
Vv=buf[head];
buf[head]=null;
if(++head==buf.length)
{
head=0;
}
--count;
returnv;
}
//通过对count的判断,来确定数组是否是满的
publicsynchronizedfinalbooleanisFull()
{
returncount==buf.length;
}
publicsynchronizedfinalbooleanisEmpty()
{
returncount==0;
}
}
2、判定前提条件再执行操作
packagecn.xf.cp.ch14;
/**
*
*功能:对插入和获取元素操作进行先行检查,然后执行操作,校验不通过不予操作
*时间:下午2:33:41
*文件:GrumpyBoundedBuffer.java
*@authorAdministrator
*
*@param<V>
*/
publicclassGrumpyBoundedBuffer<V>extendsBaseBoundedBuffer<V>
{
publicGrumpyBoundedBuffer(intsize)
{
super(size);
}
publicsynchronizedvoidput(Vv)throwsException
{
//如果是满的队列,就无法插入新的元素
if(this.isFull())
{
thrownewException("队列超出");
}
this.doPut(v);
}
//同理,队列为空的就无法取出新的元素
publicsynchronizedVtake()throwsException
{
if(this.isEmpty())
{
thrownewException("队列中无元素");
}
returnthis.doTake();
}
}
3、通过轮询与休眠来实现简单的阻塞
packagecn.xf.cp.ch14;
/**
*
*功能:通过轮询与休眠来实现简单的阻塞
*时间:下午2:55:54
*文件:SleepyBoundedBuffer.java
*@authorAdministrator
*
*@param<V>
*/
publicclassSleepyBoundedBuffer<V>extendsBaseBoundedBuffer<V>
{
//2s
privatestaticfinallongSLEEP_GRANULARITY=2000;
publicSleepyBoundedBuffer(intcapacity)
{
super(capacity);
}
//放入队列的时候
publicvoidput(Vv)throwsInterruptedException
{
while(true)
{
//这里不对循环上锁,不然这个锁就无法释放了,不对休眠上锁,休眠上锁,在休眠的时候别人也无法操作,永远都不可能有元素出去
synchronized(this)
{
//如果队列不是满的,那么就放入元素
if(!this.isFull())
{
this.doPut(v);
return;
}
}
//否则休眠,退出cpu占用
Thread.sleep(SLEEP_GRANULARITY);
}
}
publicVtake()throwsInterruptedException
{
while(true)
{
//这里不对循环上锁,不然这个锁就无法释放了,不对休眠上锁,休眠上锁,在休眠的时候别人也无法操作,永远都不可能有新的元素进来
synchronized(this)
{
//如果数组部位空,那么就可以取出数据
if(!this.isEmpty())
{
returnthis.doTake();
}
//如果队列为空,休眠几秒再试
}
Thread.sleep(SLEEP_GRANULARITY);
}
}
}
4、条件队列
packagecn.xf.cp.ch14;
/**
*
*功能:使用条件队列
*时间:下午3:32:04
*文件:BoundedBuffer.java
*@authorAdministrator
*
*@param<V>
*/
publicclassBoundedBuffer<V>extendsBaseBoundedBuffer<V>
{
publicBoundedBuffer(intcapacity)
{
super(capacity);
}
/**
*放入数据元素
*@paramv
*@throwsInterruptedException
*/
publicsynchronizedvoidput(Vv)throwsInterruptedException
{
while(this.isFull())
{
//这里挂起程序,会释放锁
this.wait();
}
//如果队列不为满的,那么程序被唤醒之后从新获取锁
this.doPut(v);
//执行结束,唤醒其他队列
this.notifyAll();
}
publicsynchronizedVtake()throwsInterruptedException
{
while(this.isEmpty())
{
this.wait();
}
Vv=this.doTake();
this.notifyAll();
returnv;
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!