MpscGrowableArrayQueue分析

MpscGrowableArrayQueue是JCTools库中的一个多生产者单消费者队列,适用于Netty和Caffeine等场景。它通过无锁的Lock-free设计和自动扩展容量提供高性能。初始化时创建初始大小的数组,并通过CAS操作和padding解决并发问题。在使用时,需确保只有一个线程进行poll操作以避免并发问题。
摘要由CSDN通过智能技术生成

概要

MpscGrowableArrayQueue是JCTools里的一个工具,是对于特定场景化的定制,即MPSC(Multi-Producer & Single-Consumer),在这种场景下,相对于BlockingQueue,能够满足高性能的需要。

背景

JCTools是一款对jdk并发数据结构进行增强的并发工具,主要提供了map以及queue的增强数据结构。

Mpsc**ArrayQueue是由JCTools提供的一个多生产者单个消费者的数组队列。多个生产者同时并发的访问队列是线程安全的,但是同一时刻只允许一个消费者访问队列,这是需要程序控制的,因为MpscQueue的用途即为多个生成者可同时访问队列,但只有一个消费者会访问队列的情况。如果是其他情况你可以使用JCTools提供的其他队列。

应用场景

上面说了MpscGrowableArrayQueue是用于特定化场景,即MPSC。其实这种场景我们平时也会看到很多,在各种框架、工具中也有它的身影。

Netty

原来Netty还是自己写的MpscLinkedQueueNode,后来新版本就换成使用JCTools的并发队列了。

Netty的线程模型决定了taskQueue可以用多个生产者线程同时提交任务,但只会有EventLoop所在线程来消费taskQueue队列中的任务。这样JCTools提供的MpscQueue完全符合Netty线程模式的使用场景。而LinkedBlockingQueue会在生产者线程操作队列时以及消费者线程操作队列时都对队列加锁以保证线程安全性。虽然,在Netty的线程模型中程序会控制访问taskQueue的始终都会是EventLoop所在线程,这时会使用偏向锁来降低线程获得锁的代价。

Caffeine

像我的一篇文章说的(Caffeine高性能设计剖析),如果对Caffeine设置了expireAfterWrite或refreshAfterWrite,那么每次写操作都会把afterWrite的task放在一个MpscGrowableArrayQueue里,之后再异步处理这些task。一般写操作有可能并发进行,有多个生产者, 但是只用一个线程来处理,来降低复杂度,这里的场景就很适合mpsc了。

使用

MpscGrowableArrayQueue的使用跟其他queue类似,提供offerpollpeek等常规方法,但由于特定化的场景,由于设计上的原因,做了一点限制,相当于牺牲了一些功能,不支持这三个方法:remove(Object o),removeAll(Collection),retainAll(Collection)。

原理分析

BlockingQueue对于每次的读写都会使用锁Lock来阻塞操作,这样在高并发下会产生性能问题,影响程序的吞吐量,那么对于这种情况的优化,很自然就会想到要把锁去掉,采用Lock-free的设计,这是生产端的原理;对于消费端,干脆只限制只有一个线程来使用(没有强制限制),那么就不存在并发问题了。

下面我们来看看MpscGrowableArrayQueue的具体实现(源码基于jctools的3.0.0版本

):

基本属性

 

MpscGrowableArrayQueueMpscChunkedArrayQueue的功能差不多,他们都继承于BaseMpscLinkedArrayQueue类。

相对于其他Mpsc**Queue类,MpscChunkedArrayQueue根据名字可以看出它是基于数组实现,跟准确的说是数组链表。这点可从它的父类BaseMpscLinkedArrayQueue看出。它融合了链表和数组,既可以动态变化长度,同时不会像链表频繁分配Node。并且吞吐量优于传统的链表。

BaseMpscLinkedArrayQueue实现了绝大部分的核心功能,下面讲到的源码都在这个类里面。

看看官方对MpscGrowableArrayQueue的定义:

1
2
3
4
5
6
7
/**
 * An MPSC array queue which starts at <i>initialCap
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值