java集合包LinkedBlockingQueue底层源码分析
一、demopublic class LinkedBlockingQueueTest { public static void main(String[] args) throws Exception{ LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue(10); linkedBlockingQueue.put("今天头条"); System.out.println(linkedBlockingQueue.take()); Iterator iterator = linkedBlockingQueue.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } }二、构造方法分析
Condition:如果你获取了一把锁,然后调用了Condition.await(),此时会释放锁,当前线程会进入一个cnodition等待队列,事后人家来唤醒你,Cnodition.signal(),这个时候会从condition等待队列中把你加入到wait等待队列里去,然后人家释放锁,就会唤醒wait等待队列里的线程尝试来获取锁; /** 当前队列元素数量 */ private final AtomicInteger count = new AtomicInteger(); /** Lock held by take, poll, etc */ /** 获取队列元素时加的锁 */ private final ReentrantLock takeLock = new ReentrantLock(); /** Wait queue for waiting takes */ private final Condition notEmpty = takeLock.newCondition(); /** Lock held by put, offer, etc */ /** 放入元素时加的锁*/ private final ReentrantLock putLock = new ReentrantLock(); /** Wait queue for waiting puts */ private final Condition notFull = putLock.newCondition(); public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); /** 队列最大大小 */ this.capacity = capacity; /** last和head指针指向空节点 */ last = head = new Node(null); }三、put方法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); /** 获取添加元素的锁 */ final ReentrantLock putLock = this.putLock; /** 获取队列当前数量 */ final AtomicInteger count = this.count; /** 加一个可以被中断的锁,保证同一时间只有一个线程可以添加数据 * 如果加锁线程被中断了,此时加锁会失败,抛出一个线程中断的异常出来 */ putLock.lockInterruptibly(); try { /* * Note that count is used in wait guard even though it is * not protected by lock. This works because count can * only decrease at this point (all other puts are shut * out by lock), and we (or some other waiting put) are * signalled if it ever changes from capacity. Similarly * for all other uses of count in other wait guards. */ /** 判断队列是否已经满了 */ while (count.get() == capacity) { /** 调用添加元素锁的Condition的await方法进入等待队列进行等待,并且释放锁 */ notFull.await(); } /** 设置尾节点的下一个节点为新创建节点 * 将新创建节点设置为尾节点 */ enqueue(node); /** 调用getAndIncrement方法,先获取count数量,在将count队列元素加一 */ c = count.getAndIncrement(); /** 判断当前元素小于队列最大数量则唤醒等待线程继续放入元素 */ if (c + 1 < capacity) notFull.signal(); } finally { /** 释放锁 */ putLock.unlock(); } /** 如果队列之前为空的话,则调用signalNotEmpty方法唤醒之前等待消费的线程进行消费 */ if (c == 0) signalNotEmpty(); }static class Node { E item; /** 指向下一个节点 */ Node next; Node(E x) { item = x; } }private void enqueue(Node node) { // assert putLock.isHeldByCurrentThread(); // assert last.next == null; /** 设置尾节点的下一个节点为新创建节点 * 将新创建节点设置为尾节点 */ last = last.next = node; }private void signalNotEmpty() { final ReentrantLock takeLock = this.takeLock; takeLock.lock(); try { /** 唤醒阻塞的消费线程 */ notEmpty.signal(); } finally { takeLock.unlock(); } }四、take方法public E take() throws InterruptedException { E x; int c = -1; /** 获取队列中元素数量 */ final AtomicInteger count = this.count; /** 获取元素出队锁 */ final ReentrantLock takeLock = this.takeLock; /** 加一个可以被中断的锁,保证同一时间只有一个线程可以添加数据 * 如果加锁线程被中断了,此时加锁会失败,抛出一个线程中断的异常出来 */ takeLock.lockInterruptibly(); try { while (count.get() == 0) { notEmpty.await(); } /** 获取第一个元素 */ x = dequeue(); /** 调用getAndIncrement方法,先获取count数量,在将count队列元素加一 */ c = count.getAndDecrement(); if (c > 1) /** 如果当前队列数量大于1则进行唤醒其他等待消费线程 */ notEmpty.signal(); } finally { /** 释放锁 */ takeLock.unlock(); } /** 判断队列之前是否已经满了,满了说明可能有有线程在等待 * 则调用signalNotFull唤醒等待线程 */ if (c == capacity) signalNotFull(); return x; }private E dequeue() { // assert takeLock.isHeldByCurrentThread(); // assert head.item == null; Node h = head; /** 获取头节点下一个元素,因为头节点一般为空,忽略 */ Node first = h.next; /** 将当前头节点的下一个元素指向自己,后续会gc回收掉 */ h.next = h; // help GC /** 在将下一个元素设置为头节点 */ head = first; /** 获取数据 */ E x = first.item; /** 将新的头节点元素设置为空,保证头节点元素一直为空 */ first.item = null; /** 返回数据 */ return x; }private void signalNotFull() { final ReentrantLock putLock = this.putLock; putLock.lock(); try { notFull.signal(); } finally { putLock.unlock(); } }五、iterator方法public Iterator iterator() { return new Itr(); }Itr() { /** 将队列中获取元素和添加元素的锁进行加锁 */ fullyLock(); try { current = head.next; if (current != null) currentElement = current.item; } finally { /** 对获取元素锁和添加元素锁进行释放 */ fullyUnlock(); } }public E next() { /** 将队列中获取元素和添加元素的锁进行加锁 */ fullyLock(); try { if (current == null) throw new NoSuchElementException(); E x = currentElement; lastRet = current; /** 获取下一个元素 */ current = nextNode(current); currentElement = (current == null) ? null : current.item; /** 返回元素 */ return x; } finally { /** 对获取元素锁和添加元素锁进行释放 */ fullyUnlock(); } }void fullyLock() { putLock.lock(); takeLock.lock(); }void fullyUnlock() { takeLock.unlock(); putLock.unlock(); }private Node nextNode(Node p) { for (;;) { Node s = p.next; if (s == p) return head.next; if (s == null || s.item != null) return s; p = s; } }
新能源汽车消费维权案例1产品质量问题案例据央视网,中国消费者协会公布2021年全国消协组织受理投诉情况分析,并同期发布了部分典型案例和解决建议。其中,新能源汽车举证难维权难是中消协公布的典型案例之一。例
小鹏汽车回应修改道路救援条款避免歧义,非质量问题救援将收费Tech星球3月24日消息,针对网友反映的小鹏汽车修改道路救援条款问题,小鹏汽车回应称,这是为了避免歧义而进行的优化。小鹏汽车客服表示,删除服务介绍中不限次数不限里程的表述,是为避
买新能源车,怎么选?注意啥?受油价持续上涨平日限号出行等因素影响,不少有意购车者将目光由燃油车投向了新能源汽车。购买新能源汽车需要注意什么?记者采访了从事新能源汽车销售多年的李宏涛,请他为市民做解答。油混插电
五菱宏光宣布旗下新能源车型涨价4中华网财经3月24日讯,近日,稳坐新能源汽车销量冠军的神车五菱宏光宣布涨价。据悉,五菱汽车旗下五菱宏光MINIEV系列,其在2021年全年销量426452台,一举问鼎新能源年度销冠
为什么谷歌卫星地图水平在全球遥遥领先?我国何时能赶上地图早已是人类社会不可或缺的工具,涉及军事国防国土开发经济发展等国计民生的方方面面。尤其是现代社会,出门旅行开车导航网络购物生活消费等,更是难以离开电子地图的帮助。其中,相比平面地
发布会扎堆出场,智能门锁内卷继续阳春三月,发布会纷至沓来,全屋智能霸屏满场。3月16日,华为终端召开2022年华为全屋智能及全场景新品春季发布会,3月17日,智能家居玩家云米科技也紧随其后召开2022春季战略新品
会不会选择新能源呢前两天,我在网上看到了这么一个问题,挺有意思的。达到什么条件,你会抛弃燃油车,选择新能源车,新能源车是不是该淘汰传统燃油车呢?你们觉得呢?打在弹幕里告诉我。其实这个提问,天然就预设
商务部多举措支持服务业发展引导互联网平台企业下调餐饮业商户服务费标准每经记者张怀水每经编辑陈星服务业作为我国经济的重要增长极和吸收外资的主引擎,将迎来更多支持举措。3月24日,商务部召开例行新闻发布会,商务部新闻发言人束珏婷表示,按照党中央国务院决
电脑摄像头被黑客控制怎么办?有这5点可以来避免你会在电脑上把摄像头用胶布给贴住吗?现在的隐私问题是越来越被人们所重视。特别是一些有摄像头的设备更是被广泛关注。比如笔记本电脑。经常会看到一些人用胶带把摄像头给遮挡起来。而且用的还
天玑1050发布,台积电6nm工艺,首次支持5G毫米波最近真的是捅了芯片窝了,近期已经有多款芯片发布了,如天玑1300骁龙7Gen1骁龙8Gen1。今日联发科又宣布推出旗下首款,支持5G毫米波的移动平台天玑1050芯片。先来看看芯片的
首发!讯飞智能办公本Air使用体验!墨水屏里的iPadmini,强Icarrytheuniversewithme。我将宇宙随身携带讯飞在智能办公本领域一直都是行业领先,此前已陆续上市X1X2T1T2等高端商务和入门商务本,商场反响一直不错,刚刚上