第四节(前三节是讲锁的,放到了上一个草稿中) disruptor概述
- Disruptor是一个开源的并发框架,是一个高性能的异步处理框架,或者可以认为是最快的消息框架(轻量的JMS),也可以认为是一个观察者模式的实现,或者事件监听模式的实现。
- 性能要高于BlockingQueue,BlockingQueue原理用的是悲观锁,disruptor用的是乐观锁。
- disruptor是用事件监听实现的
第五节 disruptor的原理
- disruptor最大的优点就是无锁
- disruptor也叫做高性能的无锁队列。
- disruptor底层使用的是CAS无锁机制。
- disruptor是基于事件驱动源(观察者模式),BlockingQueue是生产者,消费者模式。
BlockingQueue是生产者生产的消息主动推送到队列容器中,消费者直接从队列容器中取数据;
disruptor是生产者产生的信息主动推送给ringbuffer(就是BlockingQueue中的队列容器),当ringbuffer中有数据的时候主动给消费者,不再是消费者去取了。
-
Disruptor的核心概念
(1)ringbuffer:ringbuffer是一个环形的数组,disruptor用他来存储消息,而BlockingQueue底层用的是链表。环形的缓冲区,曾经RingBuffer是Disruptor中的最主要的对象,但从3.0之后,其职责被简化成了仅仅是通过Disruptor进行交换的数据(事件)进行存储和更新。在一些高级的场景中,RingBuffer可以由用户的自定义实现来完全代替。
(2)SequenceDisruptor:通过顺序递增的序号来编号管理通过其进行交换的数据(事件),对数据(事件)的处理过程总是沿着序号逐个递增处理。一个Sequence用于跟踪标识某个特定的时间处理者的进度。虽然一个AtomicLong也可以用于标识进度,单定义Sequence来负责问题还有另一个目的:防止不同的Sequence之间的CPU缓存伪共享。
Sequencer是Disruptor的真正核心,此接口有两个实现类,SingleProducerSequrncer,MultiProducerSequence,他们定义在生产者和消费者之间快速,正确的传递数据的并发算法。
(3)Sequence Barrier:用于保持对RingBuffer的main published Sequence和Consumer依赖的其他Consumer的Sequence的引用。Sequence Barrier还定义了决定Consumer是否还有可处理的时间的逻辑。
(4)Wait Strategy:定义了Consumer如何进行等待下一个时间的策略。(注意:Disruptor定义了多种不同的策略,针对不同的场景,提供了不一样的性能表现)
(5)Event:在Disruptor的语义中。生产者和消费者之间进行交换的数据被称为事件。他不是一个被Distruptor定义的特定类型。而是由Disruptor的使用者定义并指定。
(6)EventProcessor:EventProcessor持有特定的消费者(Consumer)的Sequence,并提供用于调用时间处理实现的时间循环。
(7)EventHandler:Disruptor定义的事件处理接口,由用户实现,用于处理事件,是Consumer的真正实现。
(8)Producer:即生产者,只是泛指调用Disruptor发布事件的用户代码,Disruptor没有定义特定的接口或类型。 -
RingBuffer是一个环形数组,长度必须是2的N次方,且该环形长度不能扩展长度,若长度过长,则依靠环形结构覆盖之前的数据。Sequence相当于是环形数组的下标,标记其在RingBuffer中的位置。
-
RingBuffer利用取模确定元素位置所在。
第六节和第七节 创建disruptor的生产端和消费端
package com.xiyou.mayi.thread5.testDisruptor;
/**
* 定义事件event(就是消费者与发送者交互的数据)
*/
public class LongEvent {
private Long value;
public Long getValue() {
return value;
}
public void setValue(Long value) {
this.value = value;
}
}
package com.xiyou.mayi.thread5.testDisruptor;
import com.lmax.disruptor.EventFactory;
/**
* 需要让Disruptor为我们创建事件,我们同时声明了一个工厂来实例化Event对象
*/
public class LongEventFactory implements EventFactory<LongEvent> {
@Override
public LongEvent newInstance() {
return new LongEvent();
}
}
package com.xiyou.mayi.thread5.testDisruptor;
import com.lmax.disruptor.EventHandler;
/**
* 事件的消费者,也就是一个事件处理器。这个事件处理器是事件监听
*/
public class LongEventHandler implements EventHandler<LongEvent> {
@Override
public void onEvent(LongEvent longEvent, long sequence, boolean endOfBatch) throws Exception {
System.out.println("消费者: " + longEvent.getValue());
}
}
package com.xiyou.mayi.thread5.testDisruptor;
import com.lmax.disruptor.RingBuffer;
import java.nio.ByteBuffer;
/**
* 定义发送者
*/
public class LongEventProducer {
private RingBuffer<LongEvent> ringBuffer;
/**
* 构造函数
* @param ringBuffer
*/
public LongEventProducer(RingBuffer<LongEvent> ringBuffer){
this.ringBuffer = ringBuffer;
}
/**
* 定义了生产者生产数据的方法,将生产的数据推送到RingBuffer中去
* @param byteBuffer
*/
public void onData(ByteBuffer byteBuffer){
// 获取事件队列下标位置,即获取当前的事件应该放到ringBuffer的哪一个位置上
long sequence = ringBuffer.next();
try {
// 取出空的队列,根据下标取出
LongEvent longEvent = ringBuffer.get(sequence);
// 给空队列赋值
longEvent.setValue(byteBuffer.getLong(0));
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("发送者无论如何到发送数据");
// 发送数据
ringBuffer.publish(sequence);
}
}
}
package com.xiyou.mayi.thread5.testDisruptor;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 启动入口
*/
public class Main {
public static void main(String[] args) {
// 创建线程池,提供给consumer
ExecutorService executor = Executors.newCachedThreadPool();
// 创建Event工厂
// 该工厂的作用就是定义一个事件
EventFactory<LongEvent> eventFactory = new LongEventFactory();
// 定义RingBuffer的大小,该大小只能是2的N次方
int ringbuffer = 1024 * 1024;
// 创建Disruptor
Disruptor<LongEvent> disruptor = new Disruptor<LongEvent>(eventFactory, ringbuffer, executor,
ProducerType.MULTI, new YieldingWaitStrategy());
// 注册消费者,告诉disruptor发送给哪个消费者,支持多个消费者,消费者不是负载均衡,而是像订阅发布一样消费同一个ringbuffer中的事件
disruptor.handleEventsWith(new LongEventHandler());
// 启动消费者
disruptor.start();
// 创建RingBuffer容器
RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer();
// 创建生产者
LongEventProducer longEventProducer = new LongEventProducer(ringBuffer);
// 指定缓冲区大小,nio发送数据
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
for (int i = 0; i < 100; i++) {
byteBuffer.putLong(0, i);
longEventProducer.onData(byteBuffer);
}
// 关闭
executor.shutdown();
disruptor.shutdown();
}
}