Disruptor简介:
1)Disruptor是一个开源框架。
2)解决高并发下队列锁得问题。
3)应用场景:生产消费。
核心设计原理:
1)环形数组结构:避免垃圾回收。
2)元素位置定位:通过位运算,加快定位速度。
3)无锁设计:消费者/生产者先申请数据位置,再读取或插入数据。
数据结构:
框架使用RingBuffer来作为队列的数据结构,RingBuffer就是一个可自定义大小的环形数组。
除数组外还有一个序列号(sequence),用以指向下一个可用的元素,供生产者与消费者使用。
关键接口说明:
1)RIngBuffer:线程交换数据得中转地,环形数组结构。
2)Sequenecer:序号管理器,负责生产者/消费者各自序号、序号栅栏管理和协调。支持单生产者和多生产者。
3)Sequence:序号,跟踪RingBuffer中任务得变化和消费者得消费情况,Disruptor通过对Sequence值同步修改实现,而非锁,这是Disruptor高性能得原因。
4)SequenceBarrier:序号栅栏,管理协调生产者序号和消费者序号,确保消费者之间按正确顺序执行,防止数据被覆盖。
5)EventProcessor:事件处理器,监听RingBuffer的事件,并消费可用事件,从RingBuffer读取的事件会交由实际的生产者实现类来消费;它会一直侦听下一个可用的序号,直到该序号对应的事件已经准备好。
6)EventHandler:业务处理器,是实际消费者的接口,完成具体的业务逻辑实现,第三方实现该接口。
7)Producer:生产者接口,第三方线程充当该角色,producer向RingBuffer写入事件。
8)Wait Strategy:决定了一个消费者怎么等待生产者将事件(Event)放入Disruptor中。
单线程写数据
Disruptor实战
1.引入依赖
<dependencies>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
2.定义事件
//定义事件event 通过Disruptor 进行交换的数据类型。
public class LongEvent {
private Long value;
public Long getValue() {
return value;
}
public void setValue(Long value) {
this.value = value;
}
}
3.定义EventFactory
public class LongEventFactory implements EventFactory<LongEvent> {
public LongEvent newInstance() {
return new LongEvent();
}
}
4.定义事件消费者
public class LongEventHandler implements EventHandler<LongEvent> {
public void onEvent(LongEvent event, long sequence, boolean endOfBatch) throws Exception {
System.out.println("消费者:"+event.getValue());
}
}
5.定义生产者
public class LongEventProducer {
public final RingBuffer<LongEvent> ringBuffer;
public LongEventProducer(RingBuffer<LongEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
}
public void onData(ByteBuffer byteBuffer) {
// 1.ringBuffer 事件队列 下一个槽
long sequence = ringBuffer.next();
Long data = null;
try {
//2.取出空的事件队列
LongEvent longEvent = ringBuffer.get(sequence);
data = byteBuffer.getLong(0);
//3.获取事件队列传递的数据
longEvent.setValue(data);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} finally {
System.out.println("生产这准备发送数据");
//4.发布事件
ringBuffer.publish(sequence);
}
}
}
6.定义Main入口
public class DisruptorMain {
public static void main(String[] args) {
// 1.创建一个可缓存的线程 提供线程来出发Consumer 的事件处理
ExecutorService executor = Executors.newCachedThreadPool();
// 2.创建工厂
EventFactory<LongEvent> eventFactory = new LongEventFactory();
// 3.创建ringBuffer 大小
int ringBufferSize = 1024 * 1024; // ringBufferSize大小一定要是2的N次方
// 4.创建Disruptor
Disruptor<LongEvent> disruptor = new Disruptor<LongEvent>(eventFactory, ringBufferSize, executor,
ProducerType.SINGLE, new YieldingWaitStrategy());
// 5.连接消费端方法
disruptor.handleEventsWith(new LongEventHandler());
// 6.启动
disruptor.start();
// 7.创建RingBuffer容器
RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer();
// 8.创建生产者
LongEventProducer producer = new LongEventProducer(ringBuffer);
// 9.指定缓冲区大小
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
for (int i = 1; i <= 100; i++) {
byteBuffer.putLong(0, i);
producer.onData(byteBuffer);
}
//10.关闭disruptor和executor
disruptor.shutdown();
executor.shutdown();
}
}