Disruptor笔记

更详细的文章: Disruptor详解

Disruptor核心概念

Disruptor:本质是无锁并发框架,用了很多的CAS来解决多线程抢夺问题,是在内存中处理。

  1. RingBuffer(环形缓冲区): 基于数组的内存级别缓存,是创建sequence(序号)与定义WaitStrategy(拒绝策略)的入口
  2. Disruptor(总体执行入口):对于RingBuffer的封装,持有RingBuffer、消费者线程池Executor、消费之集合ConsumerRepository等引用
  3. Sequence(序号分配器):对RingBuffer中的元素进行序号标记,通过顺序递增的方式李管理进行交换的数据(时间/Event),一个Sequence可以跟踪标识某个时间的处理进度,同时还能消除伪共享
  4. Sequencer(数据传输器):Sequencer里面包含了Sequence,是Disruptor的核心,Sequencee有两个实现类:SingleProducerSequencer(单生产者实现)、MultiProducerSequencer(多生产者实现),Sequencer主要作用是实现生产者和消费者之间的快递、正确传递数据的并发算法
  5. SequenceBarrier(消费者屏障):用于控制RingBuffer的Producer和Consumer之间的平衡关系,并且决定了Consumer是否还有可处理的事件的逻辑
  6. WaitStrategy(消费者等待策略):决定了消费者如何等待生产者将Event生产进Disruptor,WaitStrategy有多种实现策略
  7. Event:从生产者到消费者过程中所处理的数据单元,Event由使用者自定义
  8. EventHandler:由用户自定义实现,就是我们写消费者逻辑的地方,代表了Disruptor中的一个消费者接口
  9. EventProcessor:这个是事件处理器接口,实现了Runnable,处理主要事件循环,处理Event,拥有消费者的Sequence

WaitStrategy策略

  1. BlockingWaitStrategy策略,常见且默认的等待策略,当这个队列里满了,不执行覆盖,而是堵塞等待,使用ReentrantLock+Condition实现阻塞,最节省cpu,但高并发场景下性能最差。适合CPU资源紧缺,吞吐量和延迟并不重要的场景
  2. SleepingWaitStrategy策略,会在循环中不断等待数据。先进行自选等待如果不成功,则会使用Thread.yield()让出CPU,并最终使用LockSupport.parkNanos(1L)进行线程休眠,以确保不占用太多的CPU资源。因此这个策略会阐释比较高的平均延迟。经典的应用场景就是异步日志
    3.YieldingWaitStrategy策略,这个策略用于延时低的场合。消费者线程会不断循环监控缓冲区变化,在循环内部使用Thread.yield()让出CPU给别的线程执行时间,如果需要一个高性能的系统,并且对延时比较有严格的要求可以考虑这种策略
  3. BusySpinWaitStrategy策略,采用死循环,消费者线程会尽最大的努力监控缓冲区的变化,对延时非常苛刻的场景使用,Cpu核心数必须大于消费者线程数量,推荐在线程绑定到固定的CPU场景下使用

消费关系

        //消费消息的优先级    [ 示例 ] A -> (B,C [只会给其中的一个消费]) -> D
        disruptor.handleEventsWith(new OrderEventHandler())
                 .thenHandleEventsWithWorkerPool(new OrderEventHandler(),new OrderEventHandler())
                 .then(new OrderEventHandler())

实例

pom

 <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.3.4</version>
        </dependency>

Event

OrderEvent


import lombok.Data;

/**
 * 消息载体(事件)
 * @author qubing
 * @date 2022/1/25 14:59
 */
@Data
public class OrderEvent {

    private long value;

    private String name;

}

OrderEventFactory

import com.lmax.disruptor.EventFactory;

/**
 * 事件工厂
 * @author qubing
 * @date 2022/1/25 15:00
 */
public class OrderEventFactory implements EventFactory<OrderEvent> {
    @Override
    public OrderEvent newInstance() {
        return new OrderEvent();
    }
}


生产者

OrderEventProducer


import com.example.juc.disruptor.event.OrderEvent;
import com.lmax.disruptor.RingBuffer;

/**
 * 消息(事件) 生产者
 * @author qubing
 * @date 2022/1/25 15:02
 */
public class OrderEventProducer {

    //事件队列
    private RingBuffer<OrderEvent> ringBuffer;

    public OrderEventProducer(RingBuffer<OrderEvent> ringBuffer){
        this.ringBuffer = ringBuffer;
    }

    public void onData(long value,String name){

        //获取事件队列的下一个槽
        long sequence = ringBuffer.next();
        try {
            //获取消息(事件)
            OrderEvent orderEvent = ringBuffer.get(sequence);
            //写入数据
            orderEvent.setValue(value);
            orderEvent.setName(name);
        }catch (Exception e){
            e.printStackTrace();
        }finally {

            System.err.println("生产者"+Thread.currentThread().getName()+"发送数据value:"+value+",name:"+name);
            //发布事件
            ringBuffer.publish(sequence);
        }

    }


}

消费者

OrderEventHandler

import com.example.juc.disruptor.event.OrderEvent;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;

/**
 * 消费者
 * @author qubing
 * @date 2022/1/25 15:08
 */
public class OrderEventHandler implements EventHandler<OrderEvent>, WorkHandler<OrderEvent> {


    @Override
    public void onEvent(OrderEvent orderEvent, long sequence, boolean endOfBatch) throws Exception {

        System.err.println("消费者"+Thread.currentThread().getName()+"获取数据value:"+orderEvent.getValue()
        +",name:"+orderEvent.getName());

    }

    @Override
    public void onEvent(OrderEvent orderEvent) throws Exception {

        System.err.println("消费者"+Thread.currentThread().getName()+"获取数据value:"+orderEvent.getValue()
        +",name:"+orderEvent.getName());

    }
}

测试1

    public static void main(String[] args) {
        Disruptor<OrderEvent> disruptor = new Disruptor<>(
                OrderEvent::new,
                1024 * 1024,
                Executors.defaultThreadFactory(),
                //单生成者
                ProducerType.SINGLE,
                //等待策略
                new YieldingWaitStrategy()
        );

        //设置消费者用于处理RingBuffer的事件
        //disruptor.handleEventsWith(new OrderEventHandler());

        //设置多消费这,消息会被重复消费
        //disruptor.handleEventsWith(new OrderEventHandler(),new OrderEventHandler());

        //设置多消费者,消费者要实现WorkHandler接口,一条消息只能被一个消费者消费
        disruptor.handleEventsWithWorkerPool(new OrderEventHandler(),new OrderEventHandler());

        //启动disruptor
        disruptor.start();

        //创建ringbuffer容器
        RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();
        //创建生产者
        OrderEventProducer orderEventProducer = new OrderEventProducer(ringBuffer);
        //发送消息
        for (int i = 0; i < 100; i++) {
            orderEventProducer.onData(i,"Fox"+i);
        }

        disruptor.shutdown();


    }

测试2

   public static void main(String[] args) {
        Disruptor<OrderEvent> disruptor = new Disruptor<>(
                OrderEvent::new,
                1024 * 1024,
                Executors.defaultThreadFactory(),
                //多生成者
                ProducerType.MULTI,
                //等待策略
                new YieldingWaitStrategy()
        );

        //设置消费者用于处理RingBuffer的事件
        //disruptor.handleEventsWith(new OrderEventHandler());

        //设置多消费这,消息会被重复消费
        //disruptor.handleEventsWith(new OrderEventHandler(),new OrderEventHandler());

        //设置多消费者,消费者要实现WorkHandler接口,一条消息只能被一个消费者消费
        disruptor.handleEventsWithWorkerPool(new OrderEventHandler(),new OrderEventHandler());

        //启动disruptor
        disruptor.start();

        //创建ringbuffer容器
        RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();
        new Thread(() ->{
            //创建生产者
            OrderEventProducer orderEventProducer = new OrderEventProducer(ringBuffer);
            //发送消息
            for (int i = 0; i < 100; i++) {
                orderEventProducer.onData(i,"Fox"+i);
            }
        },"producer1").start();
        new Thread(() ->{
            //创建生产者
            OrderEventProducer orderEventProducer = new OrderEventProducer(ringBuffer);
            //发送消息
            for (int i = 0; i < 100; i++) {
                orderEventProducer.onData(i,"Monkey"+i);
            }
        },"producer2").start();

       // disruptor.shutdown();


    }

测试3



    public static void main(String[] args) {
        Disruptor<OrderEvent> disruptor = new Disruptor<>(
                OrderEvent::new,
                1024 * 1024,
                Executors.defaultThreadFactory(),
                //多生成者
                ProducerType.MULTI,
                //等待策略
                new YieldingWaitStrategy()
        );

        //设置消费者用于处理RingBuffer的事件
        //disruptor.handleEventsWith(new OrderEventHandler());

        //设置多消费这,消息会被重复消费
        //disruptor.handleEventsWith(new OrderEventHandler(),new OrderEventHandler());

        //设置多消费者,消费者要实现WorkHandler接口,一条消息只能被一个消费者消费
        //消费消息的优先级    [ 示例 ] A -> (B,C [只会给其中的一个消费]) -> D
        disruptor.handleEventsWith(new OrderEventHandler())
                 .thenHandleEventsWithWorkerPool(new OrderEventHandler(),new OrderEventHandler())
                 .then(new OrderEventHandler());

        //启动disruptor
        disruptor.start();

        //创建ringbuffer容器
        RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();
        new Thread(() ->{
            //创建生产者
            OrderEventProducer orderEventProducer = new OrderEventProducer(ringBuffer);
            //发送消息
            for (int i = 0; i < 100; i++) {
                orderEventProducer.onData(i,"Fox"+i);
            }
        },"producer1").start();


//        disruptor.shutdown();


    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值