ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LinkedBlockingQueue有界队列

2021-07-25 16:31:49  阅读:185  来源: 互联网

标签:count last 队列 LinkedBlockingQueue 线程 有界 put capacity


初始化

  创建的时候,实际就是指定了队列大小 capacity,然后队列node其实就是个单向列表结构,item 是当前元素,next 是下一个元素的引用。默认head指针和last指针都是指向这个空节点。ps: 是不是有点责任链模式的感觉呢。

put

put 从队列尾部插入节点

  1. 首先也是获取到了 ReentrantLock 锁 ,进行 putLock 加锁。
  2. 添加元素之前,先 while (count.get() == capacity) 判断一下,count 是队列中的个数,capacity 是指定的最大个数。相等就说明队列满了,那当前线程就要park挂起释放锁。
  3. enqueue(node) 这个是核心,走到这里说明可以添加元素了。 "last = last.next = node;" 这行代码的意思就是先将 last.next 的指针指向node,然后再把 last 也指向它,说明是最后一个元素(初始化的时候我们把 head last 都是指向null这个头节点的嘛,现在头节点还是保持不动)。
  4. c 是此次put前的元素个数,然后count自增1了。c + 1 < capacity 说明队列没有满,也尝试去唤醒阻塞的队列 (这种代码确实可读性不太好,像hashmap里面也是大量这样的代码)。
  5. c == 0 ,表示之前队列位空,说明可能有线程执行take操作被阻塞住了

take

take 从头部弹出节点

  1. 先获取到 ReentrantLock 锁 ,进行 takeLock 加锁。
  2. while (count.get() == 0)那就说明队列中没有元素,然后把自己挂起来一直等待(前面不是说了put也会唤醒等待的元素嘛,那个时候就会唤醒这个线程)。
  3. dequeue();就是弹出第一个节点
  4. c = count.getAndDecrement(); 首先是c = count的,然后 count-1 ,也就是说 c-count=1
  5. c > 1,也就是说task之前起码是有2个线程等待的,现在 dequeue() 之后起码还有一条数据,那就去唤醒线程
  6. c == capacity,就是说 take 之前满了,那就很可能有人put的时候阻塞了,现在就去尝试唤醒它

 

标签:count,last,队列,LinkedBlockingQueue,线程,有界,put,capacity
来源: https://www.cnblogs.com/wlwl/p/15057170.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有