二、数据消费方式

public class Trade {  
	
	private String id;//ID  
	private String name;
	private double price;//金额  
	private AtomicInteger count = new AtomicInteger(0);
}
public class TradeHandler implements EventHandler<Trade>, WorkHandler<Trade> {  
	  
    @Override  
    public void onEvent(Trade event, long sequence, boolean endOfBatch) {
        this.onEvent(event);  
    }

    /**
     * 具体的消费逻辑
     * @param event
     */
    @Override  
    public void onEvent(Trade event) {
        System.out.println("消费端获取数据:订单id="+event.getId()+",价格="+event.getPrice());
    }  
} 

一、消息处理器方式

public class Main1 {  
   
	public static void main(String[] args) throws Exception {  
        int BUFFER_SIZE = 1024;
        int THREAD_NUMBERS = 4;
        /* 
         * createSingleProducer创建一个单生产者的RingBuffer
         * 第一个参数叫EventFactory,从名字上理解就是"事件工厂",其实它的职责就是产生数据填充RingBuffer的区块。 
         * 第二个参数是RingBuffer的大小,它必须是2的指数倍 目的是为了将求模运算转为&运算提高效率 
         * 第三个参数是RingBuffer的生产都在没有可用区块的时候(可能是消费者(或者说是事件处理器) 太慢了)的等待策略 
         */  
        final RingBuffer<Trade> ringBuffer = RingBuffer.createSingleProducer(() -> new Trade(), BUFFER_SIZE, new YieldingWaitStrategy());
        
        //创建4个固定线程的线程池
        ExecutorService executors = Executors.newFixedThreadPool(THREAD_NUMBERS);
        
        //创建SequenceBarrier,充当了Producer和Consumer之间的平衡的角色,或者说定义了Consumer要如何等着
        SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();

        //创建消息处理器  构造函数的第三个参数为EventHandler接口的实现类
        BatchEventProcessor<Trade> transProcessor = new BatchEventProcessor<>(ringBuffer, sequenceBarrier, new TradeHandler());

        //这一步的目的就是把消费者的位置信息引用注入到生产者,如果只有一个消费者的情况可以省略
        ringBuffer.addGatingSequences(transProcessor.getSequence());

        //把消息处理器提交到线程池  
        executors.submit(transProcessor);
        
        //如果存在多个消费者 那重复执行上面3行代码 把TradeHandler换成其它消费者类  

        /**
         * 通过线程池提交10次数据
         */
        Future<?> future= executors.submit(new Callable<Void>() {
            @Override  
            public Void call() throws Exception {
                long sequence;
                for(int i = 0; i < 10; i++){
                    //返回ringBuffer一个可用区块
                    sequence = ringBuffer.next();
                    //给这个区块放入数据
                    Trade trade = ringBuffer.get(sequence);
                    //生成ID
                    trade.setId(UUID.randomUUID().toString());
                    //设置价格
                    trade.setPrice(Math.random() * 9999);
                    //发布这个区块的数据使handler(consumer)可见
                    ringBuffer.publish(sequence);
                }
                return null;
            }
        });

        //返回null值,表示处理完成
        Object o = future.get();
        System.out.println("future.get()得到的结果:" + o);
        //等上1秒,等消费都处理完成
        Thread.sleep(1000);
        //通知事件(或者说消息)处理器 可以结束了(并不是马上结束!!!)
        transProcessor.halt();
        //终止线程
        executors.shutdown();
    }
}

二、使用工作池

public class Main2 {  
    public static void main(String[] args) throws InterruptedException {  
        int BUFFER_SIZE=1024;  
        int THREAD_NUMBERS=4;
        EventFactory<Trade> eventFactory = new EventFactory<Trade>() {  
            public Trade newInstance() {  
                return new Trade();  
            }  
        };
        RingBuffer<Trade> ringBuffer = RingBuffer.createSingleProducer(eventFactory, BUFFER_SIZE);
        SequenceBarrier sequenceBarrier = ringBuffer.newBarrier();
        ExecutorService executor = Executors.newFixedThreadPool(THREAD_NUMBERS);
        //消费者
        WorkHandler<Trade> handler = new TradeHandler();
        //使用工作池
        WorkerPool<Trade> workerPool = new WorkerPool<>(ringBuffer, sequenceBarrier, new IgnoreExceptionHandler(), handler);
        workerPool.start(executor);
        //生产8个数据
        for (int i = 0; i < 8; i++) {
            long seq = ringBuffer.next();
            Trade trade = ringBuffer.get(seq);
            trade.setPrice(Math.random() * 9999);
            trade.setId(UUID.randomUUID().toString());
            ringBuffer.publish(seq);
        }
        Thread.sleep(1000);
        //workPool释放资源
        workerPool.halt();  
        executor.shutdown();  
    }  
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值