Java 线程间通讯库 Disruptor

Disruptor的具体原理  http://ifeve.com/disruptor/


通过cache line对齐来解决 false sharing的问题,而且是无锁的,应该比java自带的blocking queue速度要快。


这个Disruptor库用来解决生产者和消费者问题,它可以实现生产者和消费者  N:M的关系。

可实现的模式有 菱形(disruptor.handleEventsWith(c0,c1).then(c2) )

 *
 *               +----+
 *    +----->| C0 |-----+
 *    |          +----+     |
 *    |                 v
 * +----+               +----+
 * | P0 |                | C2 |
 * +----+               +----+
 *    |                 ^
 *    |          +----+     |
 *    +----->| C1 |-----+
 *              +----+
 *

管道(isruptor.handleEventsWith(c0).then(c1).then(c2))

 * +----+     +----+     +----+      +----+
 * | P0 |--->| C0 |--->| C1 |--->| C2 |
 * +----+    +----+      +----+      +----+


    后面的消费者要等到前面的消费者处理完后,才会处理该消息。菱形状态下,C0和C1并发运行,但处理的消息都是一样的。也就是说,一个生产者产生的同一个数据都会被

C0和C1处理,而不会只有C0或者C1处理。并行的意思是C0,C1,C2在不同的线程中。disruptor会为每个消费者分配一个线程。

     要注意ringbuffer的分配的大小,ringbuffer不应该太大。如果你需要一个很大的ringbuffer,说明消费者线程这边处理能力不够,需要提高消费者处理线程能力。

当然也有可能是生产者这边burst的比较厉害。消费者消费完数据后,ringbuffer仍旧引用你的数据,导致Jvm无法回收这些内存。如果确实为应对生产者的burst,而

申请一个大的ringbuffer,注意在Evnet中清理数据。这个可以通过加一个消费者,最后一个消费者处理event中引用的数据即可。


MainDisruptor.java

package example1;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;

public class MainDisruptor {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//ExecutorService executor = Executors.newFixedThreadPool(1);
		
		Disruptor<LogEvent> disruptor = new Disruptor<LogEvent>(new MyFactory(), 4, new ThreadFactory() {
			
			@Override
			public Thread newThread(Runnable r) {
				Thread t = new Thread(r);
				System.out.println("create new thread " + t.getId());
				return t;
			}
		}, 
		ProducerType.SINGLE,
		new BlockingWaitStrategy());
		
		
		new MyEventHandler(0);
		//产生三个消费者线程
		disruptor.handleEventsWith( new MyEventHandler(0),  new MyEventHandler(1) ).then( new MyEventHandler(3));
		disruptor.start();
		
		for(int i=0; i<10; i++) {
			MyData data = new MyData();
			data.orderID = i;
			data.price = Math.random();
			disruptor.publishEvent( new MyEventTranslatorOneArg(), data);
		}
		
		disruptor.shutdown();
	}

}



LogEvent.java

public class LogEvent {
	private MyData data;
	
	public void setValue(MyData data) {
		this.data = data;
	}
	
	public MyData getData() {
		return this.data;
	}
	
	public String toString() {
		return "LogEvent";
	}
}

MyData.java

public class MyData {

	public int orderID;
	public double price;
	
	public String toString() {
		
		return String.format("orderID %d, price %f", orderID, price); 
	}
}


MyEventHandler.java

import com.lmax.disruptor.EventHandler;

public class MyEventHandler implements EventHandler<LogEvent> {
	
	private int tag;
	public MyEventHandler(int tag) {
		this.tag = tag;
	}

	@Override
	public void onEvent(LogEvent event, long sequence, boolean endofBatch) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("onEvent " + sequence + " tag " + this.tag + " threadID " + Thread.currentThread().getId() + "  " + endofBatch);
	}

}

MyEventTranslatorOneArg.java


import com.lmax.disruptor.EventTranslatorOneArg;

public class MyEventTranslatorOneArg implements EventTranslatorOneArg<LogEvent, MyData> {

	@Override
	public void translateTo(LogEvent event, long sequence, MyData data) {
		System.out.println(" assit publish event sequence " + sequence + "  threadID " + Thread.currentThread().getId());
		
		event.setValue(data);
	}

}

MyFactory.java

import com.lmax.disruptor.EventFactory;

public class MyFactory implements EventFactory<LogEvent> {

	@Override
	public LogEvent newInstance() {
		// TODO Auto-generated method stub
		return new LogEvent();
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值