采用CAS算法 实现高性能的Disruptor 完成多线程下并发、等待、先后等操作
来源:https://blog.csdn.net/tianyaleixiaowu/article/details/79787377
拓展:
https://www.jianshu.com/p/d24b2eb4a881 初识Disruptor
Java完成多线程间的等待功能:
场景1:一个线程等待其他多个线程都完成后,再进行下一步操作(如裁判员计分功能,需要等待所有运动员都跑完后,才去统计分数。裁判员和每个运动员都是一个线程)。
场景2:多个线程都等待至某个状态后,再同时执行(模拟并发操作,启动100个线程 ,先启动完的需要等待其他未启动的,然后100个全部启动完毕后,再一起做某个操作)。
以上两个场景都较为常见,Java已经为上面的场景1和2分别提供了CountDownLatch和CyclicBarrier两个实现类来完成,参考另一篇文章:https://blog.csdn.net/tianyaleixiaowu/article/details/75234600
而对于更复杂的场景,如
譬如希望1执行完后才执行2,3执行完后才执行4,1和3并行执行,2和4都执行完后才执行last。
还有其他的更奇怪的执行顺序等等。当然这些也可以通过组合多个CountDownLatch或者CyclicBarrier、甚至使用wait、Lock等组合来实现。不可避免的是,都需要使用大量的锁,直接导致性能的急剧下降和多线程死锁等问题发生。那么有没有高性能的无锁的方式来完成这种复杂的需求实现呢?
那就是Disruptor!
Disruptor可以非常简单的完成这种复杂的多线程并发、等待、先后执行等。
至于Disruptor是什么就不说了,直接来看使用:
直接添加依赖包,别的什么都不需要。
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.1</version>
</dependency>
我只帖关键代码,别的上传到压缩包了。https://download.csdn.net/download/tianyaleixiaowu/10322342
import a.FirstEventHandler;
import a.LongEvent;
import a.LongEventFactory;
import a.LongEventProducer;
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType; import java.nio.ByteBuffer;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory; /**
* @author wuweifeng wrote on 2018/3/29.
*/
public class Simple {
public static void main(String[] args) {
ThreadFactory producerFactory = Executors.defaultThreadFactory();
LongEventFactory eventFactory = new LongEventFactory();
int bufferSize = 8; Disruptor<LongEvent> disruptor = new Disruptor<>(eventFactory, bufferSize, producerFactory,
ProducerType.SINGLE, new BlockingWaitStrategy()); FirstEventHandler firstEventHandler = new FirstEventHandler();
SecondEventHandler secondHandler = new SecondEventHandler();
ThirdEventHandler thirdEventHandler = new ThirdEventHandler();
FourthEventHandler fourthEventHandler = new FourthEventHandler();
LastEventHandler lastEventHandler = new LastEventHandler(); //1,2,last顺序执行
//disruptor.handleEventsWith(new LongEventHandler()).handleEventsWith(new SecondEventHandler())
// .handleEventsWith(new LastEventHandler()); //也是1,2,last顺序执行
//disruptor.handleEventsWith(firstEventHandler);
//disruptor.after(firstEventHandler).handleEventsWith(secondHandler).then(lastEventHandler); //1,2并发执行,之后才是last
//disruptor.handleEventsWith(firstEventHandler, secondHandler);
//disruptor.after(firstEventHandler, secondHandler).handleEventsWith(lastEventHandler); //1后2,3后4,1和3并发,2和4都结束后last
disruptor.handleEventsWith(firstEventHandler, thirdEventHandler);
disruptor.after(firstEventHandler).handleEventsWith(secondHandler);
disruptor.after(thirdEventHandler).handleEventsWith(fourthEventHandler);
disruptor.after(secondHandler, fourthEventHandler).handleEventsWith(lastEventHandler); disruptor.start(); RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer();
LongEventProducer longEventProducer = new LongEventProducer(ringBuffer);
ByteBuffer bb = ByteBuffer.allocate(8);
for (long i = 0; i < 10L; i++) {
bb.putLong(0, i);
longEventProducer.onData(bb);
} disruptor.shutdown();
}
}
主要就是这个类。我注释掉的部分分别为顺序执行、和12并发然后执行last。
上面那个图对应的代码主要就是after的使用。
运行结果 :

可以看到,由于buffer为8,所以在一个周期内,最大value=7.顺序就是1-3,2-4,1、3是并发的。对于同一个Event,2和4执行完后才执行last。多执行几次看看,就能看明白。
这里用的producer只打印了10个,可以调大,结果就会随机性更好。
采用CAS算法 实现高性能的Disruptor 完成多线程下并发、等待、先后等操作的更多相关文章
- 2.原子变量 CAS算法
前面提到,使用volatile无法保证 变量状态的原子性操作,所谓原子性,就是不可再分 如:i++的原子性问题,i++ 的操作实际上分为三个步骤 "读-改-写" (1)保存i的值 ...
- 高性能队列Disruptor系列1--传统队列的不足
在前一篇文章Java中的阻塞队列(BlockingQueue)中介绍了Java中的阻塞队列.从性能上我们能得出一个结论:数组优于链表,CAS优于锁.那么有没有一种队列,通过数组的方式实现,而且采用无锁 ...
- 高性能队列Disruptor系列2--浅析Disruptor
1. Disruptor简单介绍 Disruptor是一个由LMAX开源的Java并发框架.LMAX是一种新型零售金融交易平台,这个系统是建立在 JVM 平台上,核心是一个业务逻辑处理器,它能够在一个 ...
- Java多线程系列——原子类的实现(CAS算法)
1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronou ...
- (一)juc线程高级特性——volatile / CAS算法 / ConcurrentHashMap
1. volatile 关键字与内存可见性 原文地址: https://www.cnblogs.com/zjfjava/category/979088.html 内存可见性(Memory Visibi ...
- CAS 算法与 Java 原子类
乐观锁 一般而言,在并发情况下我们必须通过一定的手段来保证数据的准确性,如果没有做好并发控制,就可能导致脏读.幻读和不可重复度等一系列问题.乐观锁是人们为了应付并发问题而提出的一种思想,具体的实现则有 ...
- Compare and Swap [CAS] 算法
一个Java 5中最好的补充是对原子操作的支持类,如AtomicInteger,AtomicLong等.这些类帮助你减少复杂的(不必要的)多线程代码,实际上只是完成一些基本操作,如增加或减少多个线程之 ...
- (转)利用CAS算法实现通用线程安全状态机
在多线程环境下,如果某个类是有状态的,那我们在使用前,需要保证所有该类的实例对象状态一致,否则会出现意向不到的bug.下面是通用线程安全状态机的实现方法. public class ThreadSav ...
- 三、原子变量与CAS算法
原子变量:jdk1.5 后 java.util.concurrent.atomic 包下提供了常用的原子变量: - AtomicBoolean - AtomicInteger - AtomicLong ...
随机推荐
- java实现链栈
package linkstack; /** * Created by Administrator on 2019/4/18. */ public class LinkStack { private ...
- *args和**kwargs的区别
*args和**kwargs表示可变长度的参数. *args是元组类型: **kwargs是字典类型: 注意:arg.*args.**kwargs三个参数的位置必须是固定的,否则会报错.
- js初学
1.学习一门编程语言需要记住知识点: 1.关键字. 2.标识符. 3.注释. 4.运算符. 5.常量和变量 . 6.语句. 7.函数 ...
- 魅族pro 7详细打开Usb调试模式的方法
经常我们使用安卓手机链上Pc的时候,或者使用的有些APP比如我们公司营销小组经常使用的APP引号精灵,之前老版本就需要开启usb开发者调试模式下使用,现经常新版本不需要了,如果手机没有开启usb开发者 ...
- Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks 阅读笔记
Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks (使用循环一致的对抗网络的非配对图像-图 ...
- shell练习题5
需求如下: 用shell实现,把一个文件文档中只有一个数字的行给打印出来.(以/password文件为例,自行修改) 参考解答如下 方法1 #!/bin/bash file_name=passwd n ...
- java基础知识—类的方法
1.定义类方法的语法: 访问修饰符 返回值类型 方法名(){ 方法体: } 2.方法名的规范: 1.必须以字母下划线·“—”或“$”开头 2.可以有数字,但不能以数字开头. 3.如果方法名是以多个单词 ...
- 远程桌面服务当前正忙,因此无法完成您尝试执行的任务-win2008R2
远程桌面服务当前正忙,因此无法完成您尝试执行的任务,近来我服务器出现这情况, 到达主机房看主机...不可以登陆,也没有登陆框.只能关机. 在微软找到的原因是:Csrss.exe 进程和某些应用程序 ( ...
- 最近在研究syslog日志,就说一下syslog格式吧
syslog格式:<PRI>HEADER MESSAGE syslog的消息长度:不超过1024.syslog格式举例:<15>Jul 10 12:00:00 192.168. ...
- DWZ 在js中刷新某个navTab
当时的想法是: 上传一个文件成功后 刷新navTab ,关闭上传文件dialog. function fileNameBack(args){ //表单毁掉函数 alertMsg.correct(arg ...