Java并发编程十二 Disruptor框架RingBuffer

Java并发编程十二 Disruptor框架RingBuffer

1. RingBuffer原理

Disruptor整个框架的核心就是RingBuffer,也是为什么Disruptor为什么高效率的关键。
RingBuffer是一个首尾相连的环形数据结构,没有尾指针,只维护了一个指向下一个可用位置的序号。
详细原理查看 http://ifeve.com/dissecting-disruptor-whats-so-special/

2.RingBuffer实现的两种方式

2.1 通过EventProcessor
/**
 * Created by lyyz on 2018/5/22.
 */
public class RingBufferEventProcessorMain {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建线程池
        final ExecutorService executor = Executors.newCachedThreadPool();
        final int bufferSize = 1024;
        WaitStrategy waitStrategy = new BlockingWaitStrategy();
        EventFactory<OrderEvent> eventEventFactory = new OrderEventFactory();
        /*
         * createSingleProducer创建一个单生产者的RingBuffer,
         * 第一个参数叫EventFactory,从名字上理解就是"事件工厂",其实它的职责就是产生数据填充RingBuffer的区块。
         * 第二个参数是RingBuffer的大小,它必须是2的指数倍 目的是为了将求模运算转为&运算提高效率
         * 第三个参数是RingBuffer的生产都在没有可用区块的时候(可能是消费者(或者说是事件处理器) 太慢了)的等待策略
         */
        RingBuffer<OrderEvent> ringBuffer = RingBuffer.createSingleProducer(eventEventFactory,bufferSize,waitStrategy);
        //创建SequenceBarrier
        SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
        // 实现Eventhandler接口 
        OrderEventHandler eventHandler = new OrderEventHandler();
        //创建消息处理器
        EventProcessor eventProcessor = new BatchEventProcessor<OrderEvent>(ringBuffer,sequenceBarrier,eventHandler);
        //这一步的目的就是把消费者的位置信息引用注入到生产者    如果只有一个消费者的情况可以省略
        ringBuffer.addGatingSequences(eventProcessor.getSequence());
        //把消息处理器提交到线程池
        executor.execute(eventProcessor);
        //如果存在多个消费者 那重复执行上面3行代码 把TradeHandler换成其它消费者类

        for(int i=0;i<10;i++){
            long seq = ringBuffer.next();//占个坑 --ringBuffer一个可用区块
            OrderEvent orderEvent = ringBuffer.get(seq);//给这个区块放入 数据
            orderEvent.setId(i+"");
            orderEvent.setPrice(new Random().nextInt(100));//给这个区块放入 数据
            ringBuffer.publish(seq);//发布这个区块的数据使handler(consumer)可见
        }

        Thread.sleep(1000);//等上1秒,等消费都处理完成
        eventProcessor.halt();//通知事件(或者说消息)处理器 可以结束了(并不是马上结束!!!)
        System.out.println("总价格"+eventHandler.countPrice);
        executor.shutdown();//终止线程

    }
}
2.2 通过WorkPool
public class RingBufferWorkProcessorMain {
    public static void main(String[] args) throws InterruptedException {
        //创建线程池
        final ExecutorService executor = Executors.newCachedThreadPool();
        final int bufferSize = 1024;
        WaitStrategy waitStrategy = new BlockingWaitStrategy();
        EventFactory<OrderEvent> eventEventFactory = new OrderEventFactory();
        /*
         * createSingleProducer创建一个单生产者的RingBuffer,
         * 第一个参数叫EventFactory,从名字上理解就是"事件工厂",其实它的职责就是产生数据填充RingBuffer的区块。
         * 第二个参数是RingBuffer的大小,它必须是2的指数倍 目的是为了将求模运算转为&运算提高效率
         * 第三个参数是RingBuffer的生产都在没有可用区块的时候(可能是消费者(或者说是事件处理器) 太慢了)的等待策略
         */
        RingBuffer<OrderEvent> ringBuffer = RingBuffer.createSingleProducer(eventEventFactory,bufferSize,waitStrategy);
        //创建SequenceBarrier
        SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
        // 实现Workhandler接口 
        OrderWorkHandler workHandler = new OrderWorkHandler();
        WorkerPool<OrderEvent> workerPool = new WorkerPool<OrderEvent>(ringBuffer,sequenceBarrier,new IgnoreExceptionHandler(),workHandler);
        workerPool.start(executor);

        for(int i=0;i<10;i++){
            long seq = ringBuffer.next();//占个坑 --ringBuffer一个可用区块
            OrderEvent orderEvent = ringBuffer.get(seq);//给这个区块放入 数据
            orderEvent.setId(i+"");
            orderEvent.setPrice(new Random().nextInt(100));//给这个区块放入 数据
            ringBuffer.publish(seq);//发布这个区块的数据使handler(consumer)可见
        }

        Thread.sleep(1000);//等上1秒,等消费都处理完成
        workerPool.halt();//通知事件(或者说消息)处理器 可以结束了(并不是马上结束!!!)
        System.out.println("总价格"+workHandler.countPrice);
        executor.shutdown();//终止线程
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值