netty5笔记-线程模型4-无锁队列MpscLinkedQueue

NioEventLoop采用MpscLinkedQueue替代LinkedBlockingQueue,利用其无锁特性提升效率。MpscLinkedQueue适用于单消费者多生产者场景,仅允许一个消费者进行操作,多个生产者并发添加任务。文章介绍了MpscLinkedQueue的无锁实现原理,以及为何不支持某些操作的原因。
摘要由CSDN通过智能技术生成

        NioEventLoop里面使用了MpscLinkedQueue作为taskQueue,替换了父类中默认的LinkedBlockingQueue队列。taskQueue主要用于存放可执行任务,其调用的频率非常高,因此使用一个更高效的队列能带来很大的收益。 为什么在NioEvnetLoop里用MpscLinkedQueue替换了LinkedBlockingQueue,是使用了更好的算法?还是通过舍弃一些功能的情况来达到更高效的目的?

        我们知道LinkedBlockingQueue也是一个高效的线程安全的队列,它使用了takeLock和putLock两个锁分别作用与消费线程和生产线程,避免了消费者和生产者直接的竞争。然而在消费者之间、生产者之间依然需要竞争各自端的锁。 对于NioEventLoop来说,taskQueue只有一个消费者,即运行NioEventLoop.run()的那个线程(如果不理解这句话,可以看前一篇NioEventLoop的介绍)。也就是说消费端不需要锁, 那是不是我们去掉消费端那把锁就能提高效率了呢? 并不是!! 在只有一个消费者的情况下,获取锁的时候由于没有竞争,一个cas就能完成锁定,效率实极高的。因此只去掉消费端的锁,对于单消费者的场景是没有效率的提高的。 那么? 难道要把生产者的锁也去掉?!!  netty可以告诉你,是的。去掉takeLock,去掉puLock,让效率飞一会。。。还有一个关键是,代码简单的你想哭!!!

        好了,我们来看看MpscLinkedQueue是怎么在单消费者多生产者的场景下去锁的。

        首先,我决定把MpscLinkedQueue类的注释翻译一下,方便你有一个初步的了解,防止你没看完直接跑去实践结果发现有问题。

        1、一个无锁的支持单消费者多生产者的并发队列;

        2、 允许多个生产者同时进行以下操作:offer(Object),add(Object),addAll(Collection);

        3、只允许一个消费者进行以下操作:poll(),remove(),remove(Object),clear();

        4、以下方法不支持:remove(Object o),removeAll(Collection),retainAll(Collection);为啥不支持这三个方法? 看了后面的源码分析,也许你就知道答案了。

        首先MpscLinkedQueue里面有一堆莫名其妙的字段,这个是用来消除伪共享的(想了解伪共享,可以看看

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值