最近工作比较忙,在工作项目中,看了很多人都自己实现了一套数据任务处理机制,个人感觉有点乱,且也方便他人的后续维护,所以想到了一种数据处理模式,即生产者、缓冲队列、消费者的模式来统一大家的实现逻辑。
下面时是对Disruptor基本使用的演示。使用中需要引入依赖
com.lmax
disruptor
3.4.2
事件就是通过Disruptor进行交换的数据类型。
package com.disruptor;
public class Data {
private long value;
public long getValue() {
return value;
}
public void setValue(long value) {
this.value = value;
}
}事件工厂定义了如何实例化第一步中定义的事件。Disruptor通过EventFactory在RingBuffer中预创建Event的实例。
一个Event实例被用作一个数据槽,发布者发布前,先从RingBuffer获得一个Event的实例,然后往Event实例中插入数据,然后再发布到RingBuffer中,最后由Consumer获得Event实例并从中读取数据。
package com.disruptor;
import com.lmax.disruptor.EventFactory;
public class DataFactory implements EventFactory {
@Override
public Data newInstance() {
return new Data();
}
}package com.disruptor;
import com.lmax.disruptor.RingBuffer;
import java.nio.ByteBuffer;
public class Producer {
private final RingBuffer ringBuffer;
public Producer(RingBuffer ringBuffer) {
this.ringBuffer = ringBuffer;
}
public void pushData(ByteBuffer byteBuffer) {
long sequence = ringBuffer.next();
try {
Data even = ringBuffer.get(sequence);
even.setValue(byteBuffer.getLong(0));
} finally {
ringBuffer.publish(sequence);
}
}
}package com.disruptor;
import com.lmax.disruptor.WorkHandler;
import java.text.MessageFormat;
public class Consumer implements WorkHandler {
@Override
public void onEvent(Data data) throws Exception {
long result = data.getValue() + 1;
System.out.println(MessageFormat.format("Data process : {0} + 1 = {1}", data.getValue(), result));
}
}package com.disruptor;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import java.nio.ByteBuffer;
import java.util.concurrent.ThreadFactory;
public class Main {
private static final int NUMS = 10;
private static final int SUM = 1000000;
public static void main(String[] args) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long start = System.currentTimeMillis();
DataFactory factory = new DataFactory();
int buffersize = 1024;
Disruptor disruptor = new Disruptor(factory, buffersize, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
});
Consumer[] consumers = new Consumer[NUMS];
for (int i = 0; i < NUMS; i++) {
consumers[i] = new Consumer();
}
disruptor.handleEventsWithWorkerPool(consumers);
disruptor.start();
RingBuffer ringBuffer = disruptor.getRingBuffer();
Producer producer = new Producer(ringBuffer);
ByteBuffer bb = ByteBuffer.allocate(8);
for (long i = 0; i < SUM; i++) {
bb.putLong(0, i);
producer.pushData(bb);
System.out.println("Success producer data : " + i);
}
long end = System.currentTimeMillis();
disruptor.shutdown();
System.out.println("Total time : " + (end - start));
}
}Data process : 999,987 + 1 = 999,988
Success producer data : 999995
Data process : 999,990 + 1 = 999,991
Data process : 999,989 + 1 = 999,990
Data process : 999,991 + 1 = 999,992
Data process : 999,992 + 1 = 999,993
Data process : 999,993 + 1 = 999,994
Data process : 999,995 + 1 = 999,996
Success producer data : 999996
Success producer data : 999997
Success producer data : 999998
Success producer data : 999999
Data process : 999,994 + 1 = 999,995
Data process : 999,996 + 1 = 999,997
Data process : 999,997 + 1 = 999,998
Data process : 999,998 + 1 = 999,999
Data process : 999,999 + 1 = 1,000,000
Total time : 14202由结果展示可见,边生产、边消费。
package com.mm.demo.disruptor.translator;
import com.lmax.disruptor.EventTranslatorOneArg;
import com.mm.demo.disruptor.entity.Data;
public class DataEventTranslator implements EventTranslatorOneArg {
@Override
public void translateTo(Data event, long sequence, Long arg0) {
System.out.println(MessageFormat.format("DataEventTranslator arg0 = {0}, seq = {1}", arg0, sequence));
event.setValue(arg0);
}
}消费者每次将event的结果加1。
package com.mm.demo.disruptor.handler;
import com.lmax.disruptor.EventHandler;
import com.mm.demo.disruptor.entity.Data;
import java.text.MessageFormat;
public class D1DataEventHandler implements EventHandler {
@Override
public void onEvent(Data event, long sequence, boolean endOfBatch) throws Exception {
long result = event.getValue() + 1;
Thread t = new Thread();
String name = t.getName();
System.out.println(MessageFormat.format("consumer "+name+": {0} + 1 = {1}", event.getValue(), result));
}
}这里是使用的是EventHandler。也是使用WorkHandler,EventHandler和WorkHandler的区别是前者不需要池化,后者需要池化。
package com.mm.demo.disruptor.handler;
import com.lmax.disruptor.EventHandler;
import com.mm.demo.disruptor.entity.Data;
import java.text.MessageFormat;
public class D2DataEventHandler implements EventHandler {
@Override
public void onEvent(Data event, long sequence, boolean endOfBatch) throws Exception {
long result = event.getValue() + 2;
System.out.println(MessageFormat.format("consumer 2: {0} + 2 = {1}", event.getValue(), result));
}
}Consumer1执行完成再执行Consumer2。
package com.mm.demo.disruptor.process;
import com.lmax.disruptor.dsl.Disruptor;
import com.mm.demo.disruptor.entity.Data;
import com.mm.demo.disruptor.handler.D1DataEventHandler;
import com.mm.demo.disruptor.handler.D2DataEventHandler;
/**
* 串行依次计算
* @DateT: 2020-01-07
*/
public class Serial {
public static void serial(Disruptor disruptor) {
disruptor.handleEventsWith(new D1DataEventHandler()).then(new D2DataEventHandler());
disruptor.start();
}
}Consumer1和Consumer2同时执行。
package com.mm.demo.disruptor.process;
import com.lmax.disruptor.dsl.Disruptor;
import com.mm.demo.disruptor.entity.Data;
import com.mm.demo.disruptor.handler.D1DataEventHandler;
import com.mm.demo.disruptor.handler.D2DataEventHandler;
/**
* 并行执行
* @DateT: 2020-01-07
*/
public class Parallel {
public static void parallel(Disruptor dataDisruptor) {
dataDisruptor.handleEventsWith(new D1DataEventHandler(), new D2DataEventHandler());
dataDisruptor.start();
}
}package com.mm.demo.disruptor;
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import com.mm.demo.disruptor.entity.Data;
import com.mm.demo.disruptor.handler.D1DataEventHandler;
import com.mm.demo.disruptor.process.Parallel;
import com.mm.demo.disruptor.process.Serial;
import com.mm.demo.disruptor.translator.DataEventTranslator;
import javax.swing.plaf.synth.SynthTextAreaUI;
import java.nio.ByteBuffer;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class Main {
private static final int BUFFER = 1024 * 1024;
public static void main(String[] args) {
DataFactory factory = new DataFactory();
Disruptor disruptor = new Disruptor(factory, BUFFER, Executors.defaultThreadFactory(), ProducerType.MULTI, new BlockingWaitStrategy());
Serial.serial(disruptor);
// Parallel.parallel(disruptor);
RingBuffer ringBuffer = disruptor.getRingBuffer();
for (int i = 0; i < 2; i++) {
ringBuffer.publishEvent(new DataEventTranslator(), (long)i);
}
disruptor.shutdown();
}
}上边只演示了串行和并行的方式,其实还是通过组合的方式创建不的计算处理方式(需要创建多个事件处理器EventHandler)。
| 留言与评论(共有 0 条评论) “” |