聊聊Java中的并发队列中 有界队列和无界队列的区别

本文主要总体的说一说各种并发队列 
首先来一张全体照 
这里写图片描述

从有界无界上分 
常见的有界队列为

  • ArrayBlockingQueue 基于数组实现的阻塞队列
  • LinkedBlockingQueue 其实也是有界队列,但是不设置大小时就时Integer.MAX_VALUE,内部是基于链表实现的
  • ArrayBlockingQueue 与 LinkedBlockingQueue 对比一哈 
    • ArrayBlockingQueue 实现简单,表现稳定,添加和删除使用同一个锁,通常性能不如后者
    • LinkedBlockingQueue 添加和删除两把锁是分开的,所以竞争会小一些
  • SynchronousQueue 比较奇葩,内部容量为零,适用于元素数量少的场景,尤其特别适合做交换数据用,内部使用 队列来实现公平性的调度,使用栈来实现非公平的调度,在Java6时替换了原来的锁逻辑,使用CAS代替了
  • 上面三个队列他们也是存在共性的 
    • put take 操作都是阻塞的
    • offer poll 操作不是阻塞的,offer 队列满了会返回false不会阻塞,poll 队列为空时会返回null不会阻塞
    • 补充一点,并不是在所有场景下,非阻塞都是好的,阻塞代表着不占用CPU,在有些场景也是需要阻塞的,put take 存在必有其存在的必然性

常见的无界队列

  • ConcurrentLinkedQueue 无锁队列,底层使用CAS操作,通常具有较高吞吐量,但是具有读性能的不确定性,弱一致性——不存在如ArrayList等集合类的并发修改异常,通俗的说就是遍历时修改不会抛异常
  • PriorityBlockingQueue 具有优先级的阻塞队列
  • DelayedQueue 延时队列,使用场景 
    • 缓存:清掉缓存中超时的缓存数据
    • 任务超时处理
    • 补充:内部实现其实是采用带时间的优先队列,可重入锁,优化阻塞通知的线程元素leader
  • LinkedTransferQueue 简单的说也是进行线程间数据交换的利器,在SynchronousQueue 中就有所体现,并且并发大神 Doug Lea 对其进行了极致的优化,使用15个对象填充,加上本身4字节,总共64字节就可以避免缓存行中的伪共享问题,其实现细节较为复杂,可以说一下大致过程: 
    • 比如消费者线程从一个队列中取元素,发现队列为空,他就生成一个空元素放入队列 , 所谓空元素就是数据项字段为空。然后消费者线程在这个字段上旅转等待。这叫保留。直到一个生产者线程意欲向队例中放入一个元素,这里他发现最前面的元素的数据项字段为 NULL,他就直接把自已数据填充到这个元素中,即完成了元素的传送。大体是这个意思,这种方式优美了完成了线程之间的高效协作。参考自 
      LinkedTransferQueue_浩子的博客-CSDN博客_linkedtransferqueue
  • 现在也来说一说无界队列的共同点 
    • put 操作永远都不会阻塞,空间限制来源于系统资源的限制
    • 底层都使用CAS无锁编程

     转载自 聊聊Java中的并发队列中 有界队列和无界队列的区别_dayformyjob-CSDN博客_有界队列和无界队列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值