四、并发框架disruptor-核心知识讲解

1、介绍
本文将介绍disruptor的核心功能

  • 基础元素工厂类
  • 消费者、生产者事件处理器
  • Disruptor运作机制
  • RingBuffer数据结构深入探究
  • WaitStrategy策略器详解
  • EventProcessor核心线程详解
  • EventHandler处理器详解
  • WorkProcessor工作器详解

2、基础元素工厂类

2.1、核心概念

  • RingBuffer:
    被看作Disruptor最主要的组件,然而从3.0开始RingBuffer仅仅负责存储和更新在Disruptor中流通的数据。对一些特殊的使用场景能够被用户(使用其他数据结构)完全替代。
  • Sequence:
    Disruptor使用Sequence来表示一个特殊组件处理的序号。和Disruptor一样,每个消费者(EventProcessor)都维持着一个Sequence。大部分的并发代码依赖这些Sequence值的运转,因此Sequence支持多种当前为AtomicLong类的特性。
  • Sequencer:
    这是Disruptor真正的核心。实现了这个接口的两种生产者(单生产者和多生产者)均实现了所有的并发算法,为了在生产者和消费者之间进行准确快速的数据传递。
  • SequenceBarrier:
    由Sequencer生成,并且包含了已经发布的Sequence的引用,这些的Sequence源于Sequencer和一些独立的消费者的Sequence。它包含了决定是否有供消费者来消费的Event的逻辑
  • WaitStrategy:决定一个消费者将如何等待生产者将Event置入Disruptor。
  • Event:从生产者到消费者过程中所处理的数据单元。Disruptor中没有代码表示Event,因为它完全是由用户定义的。
  • EventProcessor:主要事件循环,处理Disruptor中的Event,并且拥有消费者的Sequence。它有一个实现类是BatchEventProcessor,包含了event loop有效的实现,并且将回调到一个EventHandler接口的实现对象。
  • EventHandler:由用户实现并且代表了Disruptor中的一个消费者的接口。
  • Producer:由用户实现,它调用RingBuffer来插入事件(Event),在Disruptor中没有相应的实现代码,由用户实现。
  • WorkProcessor:确保每个sequence只被一个processor消费,在同一个WorkPool中的处理多个WorkProcessor不会消费同样的sequence。
  • WorkerPool:一个WorkProcessor池,其中WorkProcessor将消费Sequence,所以任务可以在实现WorkHandler接口的worker之间移交
  • LifecycleAware:当BatchEventProcessor启动和停止时,于实现这个接口用于接收通知。

主要讲解下面的多生产多消费图解

四、并发框架disruptor-核心知识讲解_第1张图片

2.2、快速开启一个disruptor的步骤

  • 建立一个工厂Event类,用于创建Event类实例对象
  • 需要有一个监听事件类,用于处理数据(Event 类)
  • 实例化Distruptor实例,配置一系列参数,编写Disruptor核心组件
  • 编写生产者组件,向Disruptor容器中投递数据

下面是具体的代码实现,在开始之前先加入maven的依赖

    
            com.lmax
            disruptor
            3.4.2
    

2.2.1、Event类

@Data
public class OrderEvent {

    /**
     * 订单的价格
    */
    private long value;
}

2.2.2、Event返回对象

public class OrderEventFactory implements EventFactory {
    @Override
    public OrderEvent newInstance() {
        // 这个方法就是为了返回空的数据对象(Event)
        return new OrderEvent();
    }
}

2.2.3、监听消费者类

public class OrderEventHandler implements EventHandler {
   @Override
    public void onEvent(OrderEvent orderEvent, long l, boolean b) throws Exception {
        System.out.println("监听消费者" + orderEvent.getValue());
    }
}

2.2.4、生产者

public class OrderEventProducer {
    private RingBuffer ringBuffer;

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

    public void sendData(ByteBuffer data){
        // 1.在生产者发送消息的时候,首先 需要从我么的ringBuffer里面获取一个可用的序号
        long sequence = ringBuffer.next();
        try {
            // 2.根据这个序号,找到具体的"OrderEvent"元素,注意:此时获取的OrderEvent对象是一个没用被赋值的"空对象"
            OrderEvent event = ringBuffer.get(sequence);
            // 3.进行实际的赋值处理
            event.setValue(data.getLong(0));
        }finally {
            // 4.提交操作
            ringBuffer.publish(sequence);
        }

    }
}

2.2.5、实现类

public class Main {
    public static void main(String[] args) {
        Long start = System.currentTimeMillis();
        // 参数准备工作
        OrderEventFactory orderEventFactory = new OrderEventFactory();
        int ringBufferSize = 1024 * 1024;
        // 线程
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        /**
         * 1 eventFactory: 消息(event)工厂对象
         * 2 ringBufferSize: 容器的长度
         * 3 executorService:线程池(建议使用自定义线程池)RejectedExecutionHandler
         * 4 ProducerType:单生产者还是多生产者
         * 5 waitStrategy:等待策略
        */
        // 1.实例化disruptor对象
        Disruptor disruptor = new Disruptor(orderEventFactory,
                ringBufferSize,
                executorService,
                ProducerType.SINGLE,
                new BlockingWaitStrategy()
                );
        // 2.添加消费者的监听(构建disruptor与消费者的一个关联关系)
        disruptor.handleEventsWith(new OrderEventHandler());
        // 3. 启动disruptor
        disruptor.start();
        // 4. 获取实际存储数据的容器:RingBuffer
        RingBuffer ringBuffer = disruptor.getRingBuffer();
        OrderEventProducer producer = new OrderEventProducer(ringBuffer);
        ByteBuffer bb = ByteBuffer.allocate(8);
        for (long i = 0; i<100000; i++){
            bb.putLong(0,i);
            producer.sendData(bb);
        }
        disruptor.shutdown();
        executorService.shutdown();
        Long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

你可能感兴趣的:(Java)