• Disrunptor多生产者多消费者模型讲解


    多生产者多消费者模拟需求:
    1、创建100个订单生产者,每个生产者生产100条订单,总共会生产10000条订单,由3个消费者进行订单消费处理。
    2、100个订单生产者全部创建完毕,再一起生产消费订单数据

    1、定义事件

    package com.ljq.multi;
    
    public class Order {
    	private String id;// ID
    	private String name;
    	private double price;// 金额
    
    	public String getId() {
    		return id;
    	}
    
    	public void setId(String id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public double getPrice() {
    		return price;
    	}
    
    	public void setPrice(double price) {
    		this.price = price;
    	}
    
    }
    

      

    2、生产者

    package com.ljq.multi;
    
    import com.lmax.disruptor.RingBuffer;
    
    /**
     * 生产者
     * 
     * @author Administrator
     *
     */
    public class Producer {
    	private final RingBuffer<Order> ringBuffer;
    
    	public Producer(RingBuffer<Order> ringBuffer) {
    		this.ringBuffer = ringBuffer;
    	}
    
    	/**
    	 * onData用来发布事件,每调用一次就发布一次事件 它的参数会用过事件传递给消费者
    	 */
    	public void onData(String data) {
    		// 可以把ringBuffer看做一个事件队列,那么next就是得到下面一个事件槽
    		long sequence = ringBuffer.next();
    		try {
    			// 用上面的索引取出一个空的事件用于填充(获取该序号对应的事件对象)
    			Order order = ringBuffer.get(sequence);
    			// 获取要通过事件传递的业务数据
    			order.setId(data);
    		} finally {
    			// 发布事件
    			// 注意,最后的 ringBuffer.publish 方法必须包含在 finally 中以确保必须得到调用;如果某个请求的
    			// sequence 未被提交,将会堵塞后续的发布操作或者其它的 producer。
    			ringBuffer.publish(sequence);
    		}
    	}
    
    }
    

      

    3、消费者

    package com.ljq.multi;
    
    import java.util.concurrent.atomic.AtomicInteger;
    
    import com.lmax.disruptor.WorkHandler;
    
    public class Consumer implements WorkHandler<Order>{
    	
    	private String consumerId;
    	
    	private static AtomicInteger count = new AtomicInteger(0);
    	
    	public Consumer(String consumerId){
    		this.consumerId = consumerId;
    	}
    
    	@Override
    	public void onEvent(Order order) throws Exception {
    		count.incrementAndGet();
    		System.out.println("当前消费者: " + this.consumerId + ",消费信息:" + order.getId() + ",count:" + getCount());
    	}
    	
    	public int getCount(){
    		return count.get();
    	}
    
    }
    

      

    4、生产者消费者启动类

    package com.ljq.multi;
    
    import java.util.UUID;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.Executors;
    import java.util.concurrent.atomic.AtomicInteger;
    
    import com.lmax.disruptor.EventFactory;
    import com.lmax.disruptor.ExceptionHandler;
    import com.lmax.disruptor.RingBuffer;
    import com.lmax.disruptor.SequenceBarrier;
    import com.lmax.disruptor.WorkerPool;
    import com.lmax.disruptor.YieldingWaitStrategy;
    import com.lmax.disruptor.dsl.ProducerType;
    
    /**
     * 	disrunptor 多生产者多消费者
     *  
     * @author Administrator
     *
     */
    public class Main {
    	
    	public static void main(String[] args) throws Exception {
    
    		//创建ringBuffer
    		RingBuffer<Order> ringBuffer = 
    				RingBuffer.create(ProducerType.MULTI, 
    						new EventFactory<Order>() {  
    				            @Override  
    				            public Order newInstance() {  
    				                return new Order();  
    				            }  
    				        }, 
    				        1024 * 1024, 
    						new YieldingWaitStrategy());
    		
    		SequenceBarrier barriers = ringBuffer.newBarrier();
    		
    		//创建3个消费者消费订单数据
    		Consumer[] consumers = new Consumer[3];
    		for(int i = 0; i < consumers.length; i++){
    			consumers[i] = new Consumer("c" + i);
    		}
    		
    		WorkerPool<Order> workerPool = 
    				new WorkerPool<Order>(ringBuffer, 
    						barriers, 
    						new IntEventExceptionHandler(),
    						consumers);
    		
            ringBuffer.addGatingSequences(workerPool.getWorkerSequences());  
            workerPool.start(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()));  
            
          
            final AtomicInteger count = new AtomicInteger(0);
            final CountDownLatch latch = new CountDownLatch(1);
            //100个生产者
            for (int i = 0; i < 100; i++) {  
            	final Producer p = new Producer(ringBuffer); 
            	new Thread(new Runnable() {
    				@Override
    				public void run() {
    					try {
    						System.out.println(count.incrementAndGet());
    						latch.await(); //等待,直到100个生产者创建完成,再一起生产消费订单数据
    						
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					
    					//每个生产者生产100条订单
    					for(int j = 0; j < 100; j ++){
    						p.onData(UUID.randomUUID().toString());
    					}
    				}
    			}).start();
            } 
            System.out.println("---------------开始生产-----------------");
      
            latch.countDown(); //生产者全部创建完毕,开始生产订单
            
    	}
    	
    	static class IntEventExceptionHandler implements ExceptionHandler {  
    	    public void handleEventException(Throwable ex, long sequence, Object event) {}  
    	    public void handleOnStartException(Throwable ex) {}  
    	    public void handleOnShutdownException(Throwable ex) {}  
    	} 
    }
    

      

  • 相关阅读:
    洛谷P5661 公交换乘(二分)
    洛谷P4047 [JSOI2010]部落划分(最小生成树)
    洛谷P2872 [USACO07DEC]Building Roads S(最小生成树)
    卸载重装VirtualBox回滚报错
    POJ1151 Atlantis(扫描线+线段树+离散化)
    QT入门-信号槽拓展
    Vue模板语法与常用指令总结
    Vue 生命周期
    querySelector和getElementById方法的区别
    ES6 Class(类)的继承与常用方法
  • 原文地址:https://www.cnblogs.com/linjiqin/p/7468755.html
Copyright © 2020-2023  润新知