一.代码
1.单生产者,单个消费
单个生产,单个消费主函数
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
/**
* 单个生产者,单个消费者
*/
public class SingleDisruptorTest {
public static void main(String[] args) {
OrderEventFactor eventFactory = new OrderEventFactor();
int ringBufferSize = 4;
//创建线程工厂,为了线程命名
ThreadFactory tf = new CustomizableThreadFactory("springThread-pool-");
ExecutorService executorService = Executors.newFixedThreadPool(5, tf);
Disruptor<OrderEvent> disruptor = new Disruptor(
eventFactory,
ringBufferSize,
executorService,
ProducerType.SINGLE,
new YieldingWaitStrategy());
//消费者监听
disruptor.handleEventsWith(new OrderEventHandle());
disruptor.start();
RingBuffer<OrderEvent> ringBuffer = disruptor.getRingBuffer();
//初始化生产者
OrderEventProducer orderEventProducer = new OrderEventProducer(ringBuffer);
ByteBuffer buffer = ByteBuffer.allocate(8);
for (long i = 0; i < 5; i++) {
buffer.putLong(0, i);
//发送数据
orderEventProducer.sendData(buffer);
}
disruptor.shutdown();
executorService.shutdown();
}
}
数据model
import lombok.Data;
@Data
public class OrderEvent {
private Long value;
private String name;
}
数据工厂
public class OrderEventFactor implements EventFactory<OrderEvent> {
@Override
public OrderEvent newInstance() {
return new OrderEvent();
}
}
生产者
import com.lmax.disruptor.RingBuffer;
import java.nio.ByteBuffer;
public class OrderEventProducer {
private RingBuffer<OrderEvent> ringBuffer;
public OrderEventProducer(RingBuffer<OrderEvent> ringBuffer) {
this.ringBuffer = ringBuffer;
}
public void sendData(ByteBuffer byteBuffer) {
//1.在生产者发送消息时,在RingBuff中获取一个可用的序号
long sequence = ringBuffer.next();
try {
//2.根据序号找到对应的event,这个event还没有被赋值
OrderEvent orderEvent = ringBuffer.get(sequence);
//3.进行赋值处理
orderEvent.setValue(byteBuffer.getLong(0));
} finally {
//4.进行发布
ringBuffer.publish(sequence);
}
}
}
消费者
import com.lmax.disruptor.EventHandler;
public class OrderEventHandle implements EventHandler<OrderEvent> {
@Override
public void onEvent(OrderEvent event, long sequence, boolean endOfBatch) throws Exception {
System.out.println("线程名"+Thread.currentThread().getName()+"消费者:"+event.getValue());
}
}
2.多生产者,多消费
package leetcode.editor.cn.disruptor;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
/**
* 多个生产者,多个消费者
*/
public class MultiDisruptorTest {
public static void main(String[] args) throws InterruptedException {
OrderEventFactor eventFactory = new OrderEventFactor();
int ringBufferSize = 4;
//创建线程工厂,为了线程命名
ThreadFactory tf = new CustomizableThreadFactory("springThread-pool-");
ExecutorService executorService = Executors.newFixedThreadPool(5, tf);
Disruptor<OrderEvent> disruptor = new Disruptor(
eventFactory,
ringBufferSize,
executorService,
ProducerType.MULTI,
new YieldingWaitStrategy());
//串行操作
//disruptor.handleEventsWith(new Handle1()).handleEventsWith(new Handle2()).handleEventsWith(new Handle3());
//并行操作
//disruptor.handleEventsWith(new Handle1(),new Handle2(),new Handle3());
//菱形操作,handle1和handle2并行执行,然后handle3在执行
disruptor.handleEventsWith(new Handle1(),new Handle2()).then(new Handle3());
disruptor.start();
CountDownLatch latch=new CountDownLatch(1);
ExecutorService es = Executors.newFixedThreadPool((int)latch.getCount());
for (long i = 0; i < latch.getCount(); i++) {
//发送数据
es.submit(new OrderEventTranslateProducer(disruptor,latch));
}
latch.await();
es.shutdown();
disruptor.shutdown();
executorService.shutdown();
}
}
使用EventTranslator来发送事件,不用手动的处理sequence。更加便捷
import com.lmax.disruptor.EventTranslator;
import com.lmax.disruptor.dsl.Disruptor;
import java.util.concurrent.CountDownLatch;
public class OrderEventTranslateProducer implements Runnable {
private Disruptor<OrderEvent> disruptor;
private CountDownLatch latch;
public OrderEventTranslateProducer(Disruptor<OrderEvent> disruptor, CountDownLatch latch) {
this.disruptor = disruptor;
this.latch = latch;
}
@Override
public void run() {
disruptor.publishEvent(new OrderEventTranslator());
latch.countDown();
}
}
class OrderEventTranslator implements EventTranslator<OrderEvent> {
@Override
public void translateTo(OrderEvent event, long sequence) {
}
}
创建3个消费者
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;
import java.util.Random;
public class Handle1 implements EventHandler<OrderEvent>,WorkHandler<OrderEvent> {
@Override
public void onEvent(OrderEvent event) throws Exception {
Thread.sleep(1000);
long v= new Random().nextLong()*9999;
event.setValue(new Random().nextLong()*9999);
System.out.println("线程:"+Thread.currentThread().getName()+",设置价格:"+v);
}
@Override
public void onEvent(OrderEvent event, long sequence, boolean endOfBatch) throws Exception {
this.onEvent(event);
}
}
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;
import java.util.Random;
public class Handle2 implements EventHandler<OrderEvent>, WorkHandler<OrderEvent> {
@Override
public void onEvent(OrderEvent event, long sequence, boolean endOfBatch) throws Exception {
this.onEvent(event);
}
@Override
public void onEvent(OrderEvent event) throws Exception {
Thread.sleep(1000);
String name = Handle2.getName();
event.setName(name);
System.out.println("线程:"+Thread.currentThread().getName()+",设置name:"+name);
}
public static String getName(){
String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random1=new Random();
//指定字符串长度,拼接字符并toString
StringBuffer sb=new StringBuffer();
for (int i = 0; i < 6; i++) {
//获取指定长度的字符串中任意一个字符的索引值
int number=random1.nextInt(str.length());
//根据索引值获取对应的字符char
char charAt = str.charAt(number);
sb.append(charAt);
}
String str1 = sb.toString();
return str1;
}
}
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;
public class Handle3 implements EventHandler<OrderEvent>, WorkHandler<OrderEvent> {
@Override
public void onEvent(OrderEvent event, long sequence, boolean endOfBatch) throws Exception {
this.onEvent(event);
}
@Override
public void onEvent(OrderEvent event) throws Exception {
System.out.println("线程:"+Thread.currentThread().getName()+",value:"+event.getValue()+",name:"+event.getName());
}
}
如果是菱形操作的话,handle1和handle2并行执行,然后handle3在执行
源码分析
以单个生产类型ProducerType.SINGLE
通过 ringBuffer.next()找到下一个位置。
volatile字段(cursor)的写操作创建了一个内存屏障,这个屏障将刷新所有缓存里的值(缓存失效).
消费者获取RingBuffer序列号,涉及到读冲突的缓存失效,C2在C1之后,C2拿到C1更新过的序列号之后,C2才能获取next序列号。内存屏障保证了他们之前的执行顺序,消费者总能获取最新的序列号
内存屏障作为另一个CPU级的指令,没有锁那样大的开销,volatile意味着你不用加锁,就能让获得性能的提升
@Override
public long next(int n)
{
if (n < 1)
{
throw new IllegalArgumentException("n must be > 0");
}
//初始值nextValue=-1,语义级别,下一次的可用序号
long nextValue = this.nextValue;
//下一个序号
long nextSequence = nextValue + n;
//wrapPoint 用于判断当前的序号有没有绕过整个ringBuffer容器的大小
long wrapPoint = nextSequence - bufferSize;
//这个cachedGatingSequence 目的就是不要每次都获取消费者最小序号,用一个缓存去接收,只有下面If条件满足了,才会进行赋值
long cachedGatingSequence = this.cachedValue;
if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue)
{
//内存屏障 volatile字段
cursor.setVolatile(nextValue); // StoreLoad fence
//最小的消费者的序号
long minSequence;
//如果生产者的序号大于消费者中最小的序号,就进行自旋操作
while (wrapPoint > (minSequence = Util.getMinimumSequence(gatingSequences, nextValue)))
{
LockSupport.parkNanos(1L); // TODO: Use waitStrategy to spin?
}
this.cachedValue = minSequence;
}
this.nextValue = nextSequence;
// 返回下个可用的序号
return nextSequence;
}