Java并发编程十一 Disruptor框架HelloWorld
1.简介
Disruptor是一个高性能的异步处理框架,或者可以认为是最快的消息框架(轻量的JMS),也可以认为是一个观察者模式的实现,或者事件监听模式的实现。
Disruptor能够在无锁的情况下实现网络的Queue并发操作。
2. Disruptor 关键类
RingBuffer: 被看作Disruptor最主要的组件,然而从3.0开始RingBuffer仅仅负责存储和更新在Disruptor中流通的数据。对一些特殊的使用场景能够被用户(使用其他数据结构)完全替代。
Sequence: Disruptor使用Sequence来表示一个特殊组件处理的序号。和Disruptor一样,每个消费者(EventProcessor)都维持着一个Sequence。大部分的并发代码依赖这些Sequence值的运转,因此Sequence支持多种当前为AtomicLong类的特性。
Sequencer: 这是Disruptor真正的核心。实现了这个接口的两种生产者(单生产者和多生产者)均实现了所有的并发算法,为了在生产者和消费者之间进行准确快速的数据传递。
SequenceBarrier: 由Sequencer生成,并且包含了已经发布的Sequence的引用,这些的Sequence源于Sequencer和一些独立的消费者的Sequence。它包含了决定是否有供消费者来消费的Event的逻辑。
WaitStrategy:决定一个消费者将如何等待生产者将Event置入Disruptor。
Event:从生产者到消费者过程中所处理的数据单元。Disruptor中没有代码表示Event,因为它完全是由用户定义的。
EventProcessor:主要事件循环,处理Disruptor中的Event,并且拥有消费者的Sequence。它有一个实现类是
BatchEventProcessor,包含了event loop有效的实现,并且将回调到一个EventHandler接口的实现对象。
EventHandler:由用户实现并且代表了Disruptor中的一个消费者的接口。
Producer:由用户实现,它调用RingBuffer来插入事件(Event),在Disruptor中没有相应的实现代码,由用户实现。
WorkProcessor:确保每个sequence只被一个processor消费,在同一个WorkPool中的处理多个WorkProcessor不会消费同样的sequence。
WorkerPool:一个WorkProcessor池,其中WorkProcessor将消费Sequence,所以任务可以在实现WorkHandler接口的worker吃间移交
LifecycleAware:当BatchEventProcessor启动和停止时,于实现这个接口用于接收通知。
Disruptor简单应用
1.建Event类(数据对象)
2.建立一个生产数据的工厂类,EventFactory,用于生产数据;
3.监听事件类(处理Event数据)
4.实例化Disruptor,配置参数,绑定事件;
5.建存放数据的核心 RingBuffer,生产的数据放入 RungBuffer。
public class OrderMain {
public static void main(String[] args) throws InterruptedException {
//EventFactory 创建Event工厂
EventFactory<OrderEvent> eventEventFactory = new OrderEventFactory();
//定义RingBuffer大小 必须是2的N次方
final int ringBufferSize = 1024;
// 线程工厂
ThreadFactory threadFactory = new OrderThreadFactory();
//创建disruptor
Disruptor<OrderEvent> disruptor = new Disruptor<OrderEvent>(eventEventFactory,ringBufferSize,threadFactory, ProducerType.SINGLE,new YieldingWaitStrategy());
//消息的消费者
OrderEventHandler eventHandler = new OrderEventHandler();
//绑定消息的消费者
disruptor.handleEventsWith(eventHandler);
//启动Disruptor
disruptor.start();
//得到RingBuffer (环形缓冲容器)
RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();
//实现方式一
//构建生产者 将RingBuffer传入生产者中
//OrderProducer orderProducer = new OrderProducer(ringBuffer);
//实现方式二
////构建生产者带事件翻译类 将RingBuffer传入生产者中
OrderProducerEventTranslator orderProducerEventTranslator = new OrderProducerEventTranslator(ringBuffer);
//生产者生产数据
for(int i=0;i<100;i++){
//orderProducer.newData(++i+"",new Random().nextInt(100));
orderProducerEventTranslator.newData("1",new Random().nextInt(100));
}
Thread.sleep(1000);
System.out.println("总价格"+eventHandler.countPrice);
disruptor.shutdown();
}
}
/**
* 从生产者到消费者过程中所处理的数据单元。Disruptor中没有代码表示Event,因为它完全是由用户定义的。
* Created by lyyz on 2018/5/22.
*/
public class OrderEvent {
private String id;
private long price;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getPrice() {
return price;
}
public void setPrice(long price) {
this.price = price;
}
}
/**
* 实现EventFactory接口 初始化时生成OrderEvent类
* Created by lyyz on 2018/5/22.
*/
public class OrderEventFactory implements EventFactory {
private AtomicInteger count = new AtomicInteger();
@Override
public Object newInstance() {
count.incrementAndGet();
System.out.println(this.hashCode()+ " EventFactory newInstance method"+count.get());
return new OrderEvent();
}
}
/**
* 由用户实现并且代表了Disruptor中的一个消费者的接口。
* Created by lyyz on 2018/5/22.
*/
public class OrderEventHandler implements EventHandler<OrderEvent> {
public AtomicLong countPrice = new AtomicLong();
@Override
public void onEvent(OrderEvent orderEvent, long l, boolean b) throws Exception {
System.out.println(orderEvent.getId()+" "+orderEvent.getPrice());
countPrice.addAndGet(orderEvent.getPrice());
}
}
/**
* Created by lyyz on 2018/5/22.
*/
public class OrderThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
System.out.println("Thread Factory new Thread method");
return new Thread(r);
}
}
/**
* 消息生产者类
* Created by lyyz on 2018/5/22.
*/
public class OrderProducer {
private RingBuffer<OrderEvent> ringBuffer;
public OrderProducer(RingBuffer<OrderEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
}
/**
* newData用来发布事件,每调用一次就发布一次事件
* 它的参数会用过事件传递给消费者
*/
public void newData(String id,int price){
//1.可以把ringBuffer看做一个事件队列,那么next就是得到下面一个事件槽
long sequence = ringBuffer.next();
//2.用上面的索引取出一个空的事件用于填充(获取该序号对应的事件对象)
OrderEvent orderEvent = ringBuffer.get(sequence);
//3.设置业务数据
orderEvent.setId(id);
orderEvent.setPrice(price);
//4.发布事件
ringBuffer.publish(sequence);
}
}
/**
* 消息生产者类 事件翻译
* Created by lyyz on 2018/5/22.
*/
public class OrderProducerEventTranslator {
private RingBuffer<OrderEvent> ringBuffer;
// 事件翻译者
private static final EventTranslatorTwoArg<OrderEvent, String,Integer> TRANSLATOR = new EventTranslatorTwoArg<OrderEvent, String, Integer>() {
@Override
public void translateTo(OrderEvent orderEvent, long l, String s, Integer i) {
orderEvent.setId(s);
orderEvent.setPrice(i);
}
};
public OrderProducerEventTranslator(RingBuffer<OrderEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
}
/**
* newData 发布事件
* @param id
* @param price
*/
public void newData(String id,int price) {
//发布事件 参数为事件翻译者和相应的参数
//这种形式与上种的好处是 不用通过sequence来得到消息进行业务赋值而是将这些步骤交付TRANSLATOR的translateTo方法来进行处理,
ringBuffer.publishEvent(TRANSLATOR, id, new Integer(price));
}
}