Java并发工具-JCTools简介

1,726 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

很早就有人提出了无锁队列的概念,例如:Disruptor高性能已得到生产的验证,在多个项目中例如Log4j2得到了应用和验证。在研究Netty的 HashedWheelTimer 看到有使用一个 MpscChunkedArrayQueue 队列。研究发现是使用了 JCTools 的工具。这个工具就是笔者要介绍的,这个工具的目的:旨在提供一些JDK目前缺少的并发数据结构

1. JCTools介绍

  • 并发队列的SPSC/MPSC/SPMC/MPMC变体:

    • SPSC - 单生产者、单消费者 (Wait Free, 有界队列和无界队列)
    • MPSC - 多生产者、单消费者 (锁少, 有界队列和无界队列)
    • SPMC -单生产者、多消费者 (锁少, 有界队列)
    • MPMC - 多生产者、多消费者 (锁少, 有界队列)
  • SPSC/MPSC 是Linked Array队列(有界和无界)提供了性能、分配和内存占用之间的平衡

  • 基于MPSC/MPMC XAdd的无界链接阵列队列为生产者提供了更低的争用成本(使用XAdd而不是CAS循环),并将队列块池化以减少分配。

2. JCTools使用

添加maven依赖:

<dependency>
    <groupId>org.jctools</groupId>
    <artifactId>jctools-core</artifactId>
    <version>3.3.0</version>
</dependency>

使用例子:

public class SpscTest {
​
    public static void main(String[] args) throws InterruptedException {
​
        SpscArrayQueue<Integer> queue = new SpscArrayQueue<>(2);
​
        Thread producer1 = new Thread(() -> queue.offer(1));
        producer1.start();
        producer1.join();
​
        Thread producer2 = new Thread(() -> queue.offer(2));
        producer2.start();
        producer2.join();
​
        Set<Integer> fromQueue = new HashSet<>();
        Thread consumer = new Thread(() -> queue.drain(fromQueue::add));
        consumer.start();
        consumer.join();
        fromQueue.stream().forEach(item-> System.out.println(item));
    }
​
}

运行后输出的打印结果:

1
2

在Netty HashedWheelTimer 中主要使用的是MPSC队列。

3. 性能测试

在JCTools 性能测试使用的JMH。clone JCTools到本地:

git clone https://github.com/JCTools/JCTools.git
​
cd JCTools
​
mvn clean package

然后进入 jctools-benchmarks 目录:

cd jctools-benchmarks

3.1 运行JMH Benchmarks

运行所有的JMH benchmarks:

java -jar target/microbenchmarks.jar -f <number-of-forks> -wi <number-of-warmup-iterations> -i <number-of-iterations>

列出可使用的JMH benchmarks:

java -jar target/microbenchmarks.jar -l

Tips:其他的例子可以参看github.com/JCTools/JCT…

4. 总结

对于开发的项目对于性能有较高的追求可以考虑使用JCTools,根据不同生产者和消费者的数量使用不同的队列类型。这样能够最大限度的发挥性能。

我是蚂蚁背大象,文章对你有帮助点赞关注我,文章有不正确的地方请您斧正留言评论~谢谢!

参考文档: