在linkedblockingqueue的增加元素上,也我们之前所学的ArrayBlockingQueue有相通的地方。这里我们以其中的put方法进行举例,需要加入一些锁的使用对队列进行约束。下面就linkedblockingqueue增加元素的方法进行put的使用事项讲解,同时展示出对应的代码实例。
1.put方法使用事项
(1)使用putLock加锁;
(2)如果队列满了就阻塞在notFull条件上;
(3)否则就入队;
(4)如果入队后元素数量小于容量,唤醒其它阻塞在notFull条件上的线程;
(5)释放锁;
(6)如果放元素之前队列长度为0,就唤醒notEmpty条件;
2.put增加元素实例
publicvoidput(Ee)throwsInterruptedException{ if(e==null)thrownewNullPointerException();//e不能为null intc=-1; Node<E>node=newNode<E>(e); finalReentrantLockputLock=this.putLock;//获取put锁 finalAtomicIntegercount=this.count;//获取count putLock.lockInterruptibly(); try{ while(count.get()==capacity){//如果满了,那么就需要使用notFull阻塞 notFull.await(); } enqueue(node); c=count.getAndIncrement(); if(c+1<capacity)//如果此时又有空间了,那么notFull唤醒 notFull.signal(); }finally{ putLock.unlock();//释放锁 } if(c==0)//当c为0时候,也要根take锁说一下,并发下 signalNotEmpty();//调用notEmpty } publicEtake()throwsInterruptedException{ Ex; intc=-1; finalAtomicIntegercount=this.count; finalReentrantLocktakeLock=this.takeLock; //使用takeLock加锁 takeLock.lockInterruptibly(); try{ //如果队列无元素,则阻塞在notEmpty条件上 while(count.get()==0){ notEmpty.await(); } //否则,出队 x=dequeue(); //获取出队前队列的长度 c=count.getAndDecrement(); //如果取之前队列长度大于1,则唤醒notEmpty if(c>1) notEmpty.signal(); }finally{ //释放锁 takeLock.unlock(); } //如果取之前队列长度等于容量 //则唤醒notFull if(c==capacity) signalNotFull(); returnx; } privateEdequeue(){ //head节点本身是不存储任何元素的 //这里把head删除,并把head下一个节点作为新的值 //并把其值置空,返回原来的值 Node<E>h=head; Node<E>first=h.next; h.next=h;//helpGC head=first; Ex=first.item; first.item=null; returnx; } privatevoidsignalNotFull(){ finalReentrantLockputLock=this.putLock; putLock.lock(); try{ //唤醒notFull notFull.signal(); }finally{ putLock.unlock(); } }
原文来自:https://www.py.cn
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容