阻塞队列—LinkedBlockingQueue源码分析( 四 )
poll方法去除了take方法中元素为空后阻塞等待这一步骤 , 这里也就不详细说了 。 同理 , poll(long timeout, TimeUnit unit)也和offer(E e, long timeout, TimeUnit unit)一样 , 利用了Condition的awaitNanos方法来进行阻塞等待直至超时 。 这里就不列出来说了 。
获取元素方法public E peek() {if (count.get() == 0)return null;final ReentrantLock takeLock = this.takeLock;takeLock.lock();try {Node
加锁后 , 获取到head节点的next节点 , 如果为空返回null , 如果不为空 , 返回next节点的item值 。
删除元素方法public boolean remove(Object o) {if (o == null) return false;// 两个lock全部上锁fullyLock();try {// 从head开始遍历元素 , 直到最后一个元素for (Node
因为remove方法使用两个锁全部上锁 , 所以其他操作都需要等待它完成 , 而该方法需要从head节点遍历到尾节点 , 所以时间复杂度为O(n) 。 我们来看看unlink方法 。
void unlink(Node
总结LinkedBlockingQueue是一个阻塞队列 , 内部由两个ReentrantLock来实现出入队列的线程安全 , 由各自的Condition对象的await和signal来实现等待和唤醒功能 。 它和ArrayBlockingQueue的不同点在于:
- 队列大小有所不同 , ArrayBlockingQueue是有界的初始化必须指定大小 , 而LinkedBlockingQueue可以是有界的也可以是无界的(Integer.MAX_VALUE) , 对于后者而言 , 当添加速度大于移除速度时 , 在无界的情况下 , 可能会造成内存溢出等问题 。
- 数据存储容器不同 , ArrayBlockingQueue采用的是数组作为数据存储容器 , 而LinkedBlockingQueue采用的则是以Node节点作为连接对象的链表 。
- 由于ArrayBlockingQueue采用的是数组的存储容器 , 因此在插入或删除元素时不会产生或销毁任何额外的对象实例 , 而LinkedBlockingQueue则会生成一个额外的Node对象 。 这可能在长时间内需要高效并发地处理大批量数据的时 , 对于GC可能存在较大影响 。
- 两者的实现队列添加或移除的锁不一样 , ArrayBlockingQueue实现的队列中的锁是没有分离的 , 即添加操作和移除操作采用的同一个ReenterLock锁 , 而LinkedBlockingQueue实现的队列中的锁是分离的 , 其添加采用的是putLock , 移除采用的则是takeLock , 这样能大大提高队列的吞吐量 , 也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据 , 以此来提高整个队列的并发性能 。
【阻塞队列—LinkedBlockingQueue源码分析】文章持续更新 , 可以公众号搜一搜「 一角钱技术 」第一时间阅读 ,本文 GitHub org_hejianhui/JavaStudy 已经收录 , 欢迎 Star 。
- 世代|Z星球——腾讯布局Z世代教育社交的新尝试
- 脉搏|把握时代发展脉搏,尽展巴蜀版权风采——2020年成都数字版权交易博览会成功举办
- 潜力|【国金研究】新星初现,商业化落地正当时 ——自动驾驶先行者Waymo潜力几何
- 沉浸|这里是朝阳——长楹天街“沉浸式”让消费体验再升级
- 简评|手握一个亿—Redmi Note9 Pro开箱简评
- 公司|走好科技成果转化“先手棋”——中煤集团石煤机公司依托技术创新推动高质量发展
- 分类|聊聊电商产品设计有哪些共性——商品模块
- 明细|微言普法——取证小技巧调取微信转账明细记录
- 捐赠|出乎意料——黑客勒索集团向慈善机构捐赠20000美金
- 程序员学英语第1天——JavaScript 程序测试的介绍1