ConcurrentLinkedQueue与LinkedBlockingQueue的对比

由于2采用读写锁的形式对读写进行控制,可能会在锁的获取与释放上损失一定的性能。所以当有多个消费者时多用1。

而对于2,我们在其源码中可以看到,获取队首元素有take与poll方法,这两者的最本质区别在于,当队列为空时take线程会被阻塞,调用wait()方法释放其所占有的资源。当有新元素入队时会被notify,但是对于poll,若队列为空,会直接返回null,所以在多线程中,如果消费者速度大于生产者速度,会导致队列经常为空,这时如果不在poll的返回值为空时进行必要的处理,会导致线程空转,最坏情况下会导致cpu使用率飙升。我们可以采用锁的形式在线程内部主动wait(),而在入队时notify或者notifyall来参照take方法,防止大量的线程空转。


对于1,由于其内部没有类似于2的take方法,除了poll与peek之外,没有提供别的获取元素的方法,这两者的区别在于是否会弹出队首元素。但是这时如果消费速度大于生产速度,同样会产生上面的问题,这时我们就必须采用显式的方法加锁调用wait()方法,防止cpu等资源的浪费。提高并发性能。


通过入队、出队一百万次进行性能比较

1、生产者10个,消费者100个(进队效率,后续会给出出队效率)

 takepoll+wait()poll
LinkedBlockingQueue3250 / 20%1900 / 28%至少几分钟 / 100%
ConcurrentLinkedQueue--1890 / 24%7400 / 75%
    

对比以上数据可以得出,

1、对于LinkedBlockingQueue,take方法虽然在内部实现了加锁wait(),但是由于其他的开销,导致性能相比于poll+wait()有所下降。但是如果采用poll方法,那么由于大量的线程存在空转的情况,导致争用处理机,导致性能急剧下降。

2、对于ConcurrentLinkedQueue,由于内部采用CAS保证并发安全,在采用poll+wait()时相比前者有所提升,但是不是很明显,但是对于poll方式,由于去除了锁的开销,同时虽然相比于其自身的poll+wait()方式性能下降不少,但是相对于LinkedBlockingQueue,性能提升相当明显。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值