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

Posted Ruthless

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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) {}  
	} 
}

  

以上是关于Disrunptor多生产者多消费者模型讲解的主要内容,如果未能解决你的问题,请参考以下文章

综合运用: C++11 多线程下生产者消费者模型详解(转)

多生产者多消费者问题

C ++ 11中无锁的多生产者/消费者队列

多生产者-多消费者问题

多线程_多生产者多消费者的实现问题

C++实现生产者和消费者模型