博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jdk源码之LinkedBlckingQueue源码注释
阅读量:6871 次
发布时间:2019-06-26

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

hot3.png

 今天我们分析一下LinkedBlockingQueue,这是一个我们使用频率比较高的类。

public static void main(String[] args) throws Exception {//我们这个LinkedBlockingQueue源码分三个关键步骤//步骤一:先看一个其构造函数,以及核心的属性    LinkedBlockingQueue
queue = new LinkedBlockingQueue
(); //步骤二:看一下其关键步骤,插入数据的步骤queue.put("张三");//步骤三:看一下其关键步骤,获取数据的步骤 queue.take();}步骤一:public LinkedBlockingQueue() {//设置队列的大小//其实可见,默认情况下是一个无界队列(类似于无界) this(Integer.MAX_VALUE);}public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException();//设置队列大小 this.capacity = capacity;//初始化一个空节点 last = head = new Node
(null);}//获取数据的时候的一把锁//因为是队列,这把锁在队尾private final ReentrantLock takeLock = new ReentrantLock();//关于takeLock的对象private final Condition notEmpty = takeLock.newCondition();//put数据的时候的一把锁//因为是队列,所以这把锁在队头private final ReentrantLock putLock = new ReentrantLock();//关于putLock的对象private final Condition notFull = putLock.newCondition();其实LinkedBlockingQueue的设计也是很巧妙的,使用了两把锁去控制。两把锁之间互相不影响。大幅提升了并发的性能。接下来自我们分析一下步骤二:public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); // Note: convention in all put/take/etc is to preset local var // holding count negative to indicate failure unless set. int c = -1;//根据当前传入的元素封装节点 Node
node = new Node
(e);//获取putLocak锁 final ReentrantLock putLock = this.putLock;//统计当前元数据个数 final AtomicInteger count = this.count;//加锁 putLock.lockInterruptibly(); try {//如果队列存满了,那就等待 while (count.get() == capacity) { notFull.await(); }//入队,这个操作其实也很简单// last = last.next = node; enqueue(node);//入队完了以后递增当前 元素个数//不过我们需要知道的是,比如当前的元素个数//已经是9递增到10了。//这个时候count=10 c=9 c = count.getAndIncrement();//如果c+1小于总的容量,说明队列至少有一个空间是可以存数据的。 if (c + 1 < capacity)//唤醒之前因为队列满了而处于等待的锁。 notFull.signal(); } finally {//释放锁 putLock.unlock(); }//如果c==0,说明当前的队列里面肯定还有元素,可以获取 if (c == 0)//唤醒之前因为队列为空而处于等待的锁 signalNotEmpty();}我们发现其实LinkedBlockingQueue的源码阅读下来难度不大。public E take() throws InterruptedException { E x; int c = -1;//获取当前元素个数 final AtomicInteger count = this.count;//获取takeLock锁 final ReentrantLock takeLock = this.takeLock;//获取元素的时候加锁 takeLock.lockInterruptibly(); try {//如果当前元素等于0,说明没有元素了 while (count.get() == 0) {//如果队列为空,那么就等待 notEmpty.await(); }//出队,获取元素//出队的代码也是极其简单就是变化一下指针就可以。 x = dequeue();//递减元素//加入当前count 由10 变成了9//count =10 count=9 c = count.getAndDecrement();//说明队列不为空 if (c > 1)//不为空,那么就唤醒 可能因为队列为空而处于等待的锁 notEmpty.signal(); } finally {//释放锁 takeLock.unlock(); }//如果c==capacity说明队列里面肯定会有不满的元素 if (c == capacity)//唤醒,因为队列满了而处于等待的锁。 signalNotFull();//返回当前元素 return x;}

   如果有了之前的基础,阅读这段代码应该是比较简单的。

   搞定,手工!

转载于:https://my.oschina.net/u/1464779/blog/3051313

你可能感兴趣的文章
52. N-Queens II
查看>>
字符串匹配算法
查看>>
LAMP学习路线图
查看>>
MySQL入门(四)
查看>>
详解 ML2 Core Plugin(II) - 每天5分钟玩转 OpenStack(72)
查看>>
httpd-2.2 配置及用法完全攻略
查看>>
IntelliJ_编译一直报错“找不到符号”
查看>>
【Mongodb】3.X 配置身份验证
查看>>
云计算就像马拉松 京东CTO为啥这么说
查看>>
2017阿里UCAN大会,听听大咖们都讲了啥
查看>>
每日一淘完成1.3亿美元融资:元生资本与DCM领投
查看>>
「每天一道面试题」Java虚拟机为新生对象分配内存有哪两种方式?
查看>>
海信电器于芝涛:坚守画质 才是消费者首选
查看>>
甘肃庆阳黄土塬告别“土炕”“火炉” 多措治污享蓝天
查看>>
NPM实用指北
查看>>
直播竞答必读:一定要提前知道的技术坑和新玩法
查看>>
React 中集成 Markdown编辑器
查看>>
Spring Boot 最佳实践(五)Spring Data JPA 操作 MySQL 8
查看>>
由三道题引伸出来的思考
查看>>
React 开发实战(一)- Repeat 组件
查看>>