Disruptor 简例

定义事件

/**
 * 定义event事件:通过Disruptor进行交换的数据类型
 * @author hxp
 * @create 2020-11-17 17:02
 */
public class StringEvent {

    private String value;  // 放一个字符串数据

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

定义事件工厂

/**
 * 定义事件工厂
 * @author hxp
 * @create 2020-11-17 17:04
 */
public class StirngEventFactory implements EventFactory<StringEvent> {
    @Override
    public StringEvent newInstance() {
        return new StringEvent();
    }
}

消费者 1

对于独立消费的消费者,应当实现EventHandler接口

/**
 * 消费者 ----定义事件的具体实现
 * @author hxp
 * @create 2020-11-17 17:06
 */
public class StringEventHandler implements EventHandler<StringEvent> {
    @Override
    public void onEvent(StringEvent stringEvent, long sequence, boolean endOfBatch) throws Exception {
        // 实际项目中的处理具体的业务逻辑
//        if(stringEvent.getValue().equalsIgnoreCase("2")){
//            throw new  Exception(Thread.currentThread().getName()+"终止整个任务");
//        }else {
//        }
        Thread.sleep(10);
        System.out.println(Thread.currentThread().getName()+"消费者:"+stringEvent.getValue()+ "---> sequence="+sequence+ "---> endOfBatch="+endOfBatch);
    }
}

消费者 2

对于不重复消费的消费者,应当实现WorkHandler接口。

/**
 * 消费者 ----定义事件的具体实现 不会重复消费
 * @author hxp
 * @create 2020-11-17 17:06
 */
public class StringWorkHandler implements WorkHandler<StringEvent> {
    
    @Override
    public void onEvent(StringEvent event) throws Exception {
        // 实际项目中的处理具体的业务逻辑
        if(event.getValue().contains("main6")){
//            Thread.sleep(15*1000);
            throw new  Exception(System.currentTimeMillis()+Thread.currentThread().getName()+"终止整个任务");
        }else {
            System.out.println(System.currentTimeMillis()+Thread.currentThread().getName()+"消费者消费数据"+event.getValue());
        }
            Thread.sleep(10);
    }
}

生产者

/**生产者
 * @author hxp
 * @create 2020-11-17 17:11
 */
public class StringEventProducer {

    // 核心类:环形数组
    public final RingBuffer<StringEvent> ringBuffer;

    // 构造方法初始化环形数组
    public StringEventProducer(RingBuffer<StringEvent> ringBuffer) {
        this.ringBuffer = ringBuffer;
    }

    /**
     * 生产事件(数据)的方法
     * 其实就是往环形数组里面放数据
     * @param data
     */
    public void publish(String data){
        // 1 从ringBuffer里面获取下一个序号,也就是我们要放置数据的位置
        long sequence = ringBuffer.next();
        try {
            // 2 取出空的事件队列
            StringEvent stringEvent = ringBuffer.get(sequence);
            // 3 往事件队列里面放数据
            stringEvent.setValue(data);
        } finally {
            // 4 发布事件(数据)
            ringBuffer.publish(sequence);
        }
    }
}

启动测试类

一个生产者,多个消费者

public class StringEventTest {

    public static void main(String[] args) {

        Integer consumerThread = 5;
        Integer count= 100000;

        System.out.println("消费线程数:"+consumerThread);
        System.out.println("生产事件数:"+count);

        // 事件工厂
        StirngEventFactory stringEventFactory = new StirngEventFactory();
        // 环形数组的长度最好是2的n次方
        int ringBufferSize = 2<<8;
        // 线程工厂
        ThreadFactory threadFactory = Executors.defaultThreadFactory();

        Thread thread = Thread.currentThread();
        LocalTime start = LocalTime.now();
        System.out.println("开始="+start);

        // 创建Disruptor
        Disruptor<StringEvent> disruptor = new Disruptor<>(
                stringEventFactory, // 事件(数据)工厂
                ringBufferSize,     // 环形数组的大小
                threadFactory,      // 线程工厂
                ProducerType.SINGLE, // 单个生产者
                new YieldingWaitStrategy()); // 当环形数组满的时候的等待策略

        // 设置异常处理机制
        disruptor.setDefaultExceptionHandler(new ExceptionHandler<StringEvent>() {
            @Override
            public void handleEventException(Throwable ex, long sequence, StringEvent event) {
                if (ex.toString().contains("终止整个任务")) {
                    System.out.println(ex);
                }
            }
            @Override
            public void handleOnStartException(Throwable ex) {
            }
            @Override
            public void handleOnShutdownException(Throwable ex) {
            }
        });


        /**
         * 1. 对于某一条消息m,
         * handleEventsWith方法返回的EventHandlerGroup,Group中的每个消费者都会对m进行消费,各个消费者之间不存在竞争。
         * handleEventsWithWorkerPool方法返回的EventHandlerGroup,Group的消费者对于同一条消息m不重复消费;
         * 也就是,如果c0消费了消息m,则c1不再消费消息m。
         *
         * 2. 传入的形参不同。
         * 对于独立消费的消费者,应当实现EventHandler接口。
         * 对于不重复消费的消费者,应当实现WorkHandler接口。
         */

        // 连接消费端方法 会重复消费
//        StringEventHandler[] eventHandlers = new StringEventHandler[consumerThread];
//        for (int i = 0; i < eventHandlers.length; i++) {
//            eventHandlers[i] = new StringEventHandler();
//        }
//        disruptor.handleEventsWith(eventHandlers);

        // 连接消费端方法 不会重复消费
        WorkHandler[] workHandlers = new WorkHandler[consumerThread];
        for (int i = 0; i < workHandlers.length; i++) {
            workHandlers[i] = new StringWorkHandler();
        }
        disruptor.handleEventsWithWorkerPool(workHandlers);

        // 启动消费者,先启动消费者再启动生产者
        disruptor.start();


        // 创建生产者
        RingBuffer<StringEvent> ringBuffer = disruptor.getRingBuffer();
        StringEventProducer producer = new StringEventProducer(ringBuffer);
        for (int i = 0; i < count; i++) {
            // 生产事件(数据)
            producer.publish(thread.getName()+i);
        }

        // 关闭
        disruptor.shutdown();

    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值