博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【代码积累】condition of lock
阅读量:4099 次
发布时间:2019-05-25

本文共 4326 字,大约阅读时间需要 14 分钟。

import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.ReentrantLock;public class CustomLinkedBlockingQueue
implements CustomBlockingQueue
{ private CustomHeadNode
head = null; /*至少有一个头结点,尾节点*/ private CustomTailNode
tail = null; private ReentrantLock putlock = new ReentrantLock(); private ReentrantLock takelock = new ReentrantLock(); private Condition isAvailable = takelock.newCondition(); /*If no elements are available then make take actions dormant.*/ private Condition isFull = putlock.newCondition(); /*If it's full then make put-actions dormant.*/ /*用一个原子变量记录List的长度*/ private AtomicInteger count = new AtomicInteger(0); //private CustomAtomicInteger count = new CustomAtomicInteger(0); private int capacity = 10; /*默认10*/ public CustomLinkedBlockingQueue() { super(); init(); } public CustomLinkedBlockingQueue(int capacity) { if( capacity > Integer.MAX_VALUE ) { this.capacity = Integer.MAX_VALUE; } else { this.capacity = capacity; } init(); } private void init(){ head = new CustomHeadNode
(); tail = new CustomTailNode
(); head.next = tail; tail.prev = head; } /*delete and return the head of the queue*/ private T dequeue() { if( count.get() > 0 && true!=head.next.isTail) { T value = head.next.value; if( null != value ) { /*删除中间的节点*/ head.next.next.prev = head; head.next = head.next.next; return value; } else { return null; } } else { return null; } } /*Put the specific element to the tail of the queue*/ private void enqueue(T ele) { if( count.get() < capacity ) { CustomNode
node = new CustomNode
(); node.value = ele; tail.prev.next = node; node.prev = tail.prev; node.next = tail; tail.prev = node; } } @Override /*Take a look at the head node of the LinkedList but do not remove it.*/ public T peek() { // TODO Auto-generated method stub return null; } @Override /*Remove and return the head node of the LinkedList*/ public T poll() { // TODO Auto-generated method stub T x = null; int c = -1;// final AtomicInteger count = this.count;// final ReentrantLock takelock = this.takelock; try { takelock.lockInterruptibly(); /*Acquire the lock unless the thread is interrupted.*/ /*当队列为空时,线程被挂起,直到被唤醒或者中断。如果线程被中断,根据takelock.lockInterruptibly()语句,线程将释放锁。*/ while(0 == count.get()) { isAvailable.await(); } /*队列不为空,则线程返回队列头元素*/ x = dequeue(); c = count.getAndDecrement(); /*出队列,长度计数-1*/ if(c > 1) { /*count在dequeue之前>1,dequeue后应该是1,还有数据,因此需要唤醒一个take线程*/ /*还有数据可以取,再唤醒一次take线程*/ isAvailable.signal(); } System.out.println("queue size = "+(c-1)+" after [POLL].value="+x); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { takelock.unlock(); } if( c == capacity ) { /*队列dequeue之前满了,此时必然有put线程被挂起。 * 此处需要唤醒一下put线程,否则队列满后,所有的put线程被挂起,而take线程不唤醒put线程,则所有的put线程都永远挂起了。*/ signalPutThreads(); } return x; } @Override public T take() { // TODO Auto-generated method stub return poll(); } @Override public void put(T element) { // TODO Auto-generated method stub if( element == null ) throw new NullPointerException(); int c = -1;// final AtomicInteger count = this.count;// final ReentrantLock putlock = this.putlock; try { putlock.lockInterruptibly(); while(count.get() == capacity) { isFull.await(); } enqueue(element); /*add the element to the tail and do increment.*/ c = count.getAndIncrement(); /*get the current value,increase 1 as the next value,return current and set next.*/ if( c+1 < capacity ) { isFull.signal(); } System.out.println("queue size = "+(c+1)+" after PUT.value="+element); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { putlock.unlock(); } if(c == 0) { /*这里的c保存的是queue执行enqueue之前的值,若为0,表示之前有get线程被挂起了,因此需要唤醒一个get线程*/ signalTakeThreads(); } } private void signalTakeThreads() { try { takelock.lockInterruptibly(); isAvailable.signal(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { takelock.unlock(); } } private void signalPutThreads() { try { putlock.lockInterruptibly(); isFull.signal(); /*每次唤醒一个线程,all则唤醒所有线程,但是最终执行哪个线程,取决于调度决策机制,用户无法干预。*/ } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { putlock.unlock(); } }}

转载地址:http://avhii.baihongyu.com/

你可能感兴趣的文章
C++模板
查看>>
【C#】如何实现一个迭代器
查看>>
【C#】利用Conditional属性完成编译忽略
查看>>
【Unity】微信登录后将头像存为bytes,将bytes读取成sprite图片
查看>>
【Unity】使用GPS定位经纬度
查看>>
如何高效学习动态规划?
查看>>
动态规划法(六)鸡蛋掉落问题(一)
查看>>
算法数据结构 思维导图学习系列(1)- 数据结构 8种数据结构 数组(Array)链表(Linked List)队列(Queue)栈(Stack)树(Tree)散列表(Hash)堆(Heap)图
查看>>
【机器学习】机器学习系统SysML 阅读表
查看>>
最小费用流 Bellman-Ford与Dijkstra 模板
查看>>
实现高性能纠删码引擎 | 纠删码技术详解(下)
查看>>
scala(1)----windows环境下安装scala以及idea开发环境下配置scala
查看>>
zookeeper(3)---zookeeper API的简单使用(增删改查操作)
查看>>
zookeeper(4)---监听器Watcher
查看>>
mapReduce(3)---入门示例WordCount
查看>>
hbase(3)---shell操作
查看>>
hbase(1)---概述
查看>>
hbase(5)---API示例
查看>>
SSM-CRUD(1)---环境搭建
查看>>
SSM-CRUD(2)---查询
查看>>