前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用Disruptor完成多线程下并发、等待、先后等操作

使用Disruptor完成多线程下并发、等待、先后等操作

作者头像
天涯泪小武
发布2019-01-17 12:01:17
1.7K0
发布2019-01-17 12:01:17
举报
文章被收录于专栏:SpringCloud专栏SpringCloud专栏

Java完成多线程间的等待功能:

场景1:一个线程等待其他多个线程都完成后,再进行下一步操作(如裁判员计分功能,需要等待所有运动员都跑完后,才去统计分数。裁判员和每个运动员都是一个线程)。

场景2:多个线程都等待至某个状态后,再同时执行(模拟并发操作,启动100个线程 ,先启动完的需要等待其他未启动的,然后100个全部启动完毕后,再一起做某个操作)。

以上两个场景都较为常见,Java已经为上面的场景1和2分别提供了CountDownLatch和CyclicBarrier两个实现类来完成,参考另一篇文章:https://cloud.tencent.com/developer/article/1384023

而对于更复杂的场景,如

譬如希望1执行完后才执行2,3执行完后才执行4,1和3并行执行,2和4都执行完后才执行last。

还有其他的更奇怪的执行顺序等等。当然这些也可以通过组合多个CountDownLatch或者CyclicBarrier、甚至使用wait、Lock等组合来实现。不可避免的是,都需要使用大量的锁,直接导致性能的急剧下降和多线程死锁等问题发生。那么有没有高性能的无锁的方式来完成这种复杂的需求实现呢?

那就是Disruptor!

Disruptor可以非常简单的完成这种复杂的多线程并发、等待、先后执行等。

至于Disruptor是什么就不说了,直接来看使用:

直接添加依赖包,别的什么都不需要。

代码语言:javascript
复制
<dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.1</version>
        </dependency>

我只帖关键代码,别的上传到压缩包了。https://download.csdn.net/download/tianyaleixiaowu/10322342

代码语言:javascript
复制
package b;

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个,可以调大,结果就会随机性更好。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年04月02日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档