项目的目录结构如下:
1.定义事件
package org.fenxisoft.disruptor;
//定义事件
public class LongEvent {
private long value;
public void set(long value){
this.value = value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}
2.定义事件工厂
package org.fenxisoft.disruptor;
import com.lmax.disruptor.EventFactory;
public class LongEventFactory implements EventFactory<LongEvent>{
@Override
public LongEvent newInstance() {
return new LongEvent();
}
}
3.定义事件处理者
package org.fenxisoft.disruptor;
import com.lmax.disruptor.EventHandler;
public class LongEventHandler implements EventHandler<LongEvent>{
@Override
public void onEvent(LongEvent event, long sequence, boolean endOfBatch)
throws Exception {
System.out.println(Thread.currentThread().getName()+" : "+event);
}
}
4.编写测试类
package org.fenxisoft.disruptor;
import java.util.concurrent.Executors;
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.IgnoreExceptionHandler;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.Sequence;
import com.lmax.disruptor.WaitStrategy;
import com.lmax.disruptor.WorkHandler;
import com.lmax.disruptor.WorkerPool;
import com.lmax.disruptor.dsl.ProducerType;
public class DisruptorDemo {
public static void main(String[] args) {
LongEventFactory eventFactory = new LongEventFactory();
int bufferSize = 4;//1024 * 1024;//ring Buffer Size
WaitStrategy waitStrategy = new BlockingWaitStrategy();
RingBuffer<LongEvent> ringBuffer = RingBuffer.create(ProducerType.MULTI, eventFactory,
bufferSize, waitStrategy);
WorkHandler<LongEvent> workHandler1 = new WorkHandler<LongEvent>() {
@Override
public void onEvent(LongEvent event) throws Exception {
System.out.println(Thread.currentThread().getName()+"消费数据: "+event);
}
};
WorkerPool<LongEvent> workerPool = new WorkerPool<LongEvent>(ringBuffer,
ringBuffer.newBarrier(), new IgnoreExceptionHandler(), workHandler1,workHandler1);
//每个消费者,也就是workProcessor都有一个sequence
Sequence[] sequences = workerPool.getWorkerSequences();
ringBuffer.addGatingSequences(sequences);
workerPool.start(Executors.newFixedThreadPool(10));
System.out.println("运行的线程数量:"+Thread.activeCount());//由此可以说明生产者就是主线程,消费者是两个子线程
//生产者生产数据
System.out.println("开始生产");
for(int i = 0; i < 100; i++){
long sequence = ringBuffer.next();
try {
LongEvent event = ringBuffer.get(sequence);
event.set(i);
} finally{
ringBuffer.publish(sequence);
}
System.out.println("-----------------");
}
}
}
核心方法分析:
1.next()方法分析,这个方法是单线程调用
public long next(int n)
{
if (n < 1)
{
throw new IllegalArgumentException("n must be > 0");
}
long current;//定义当前坐标
long next;//定义下次要访问的数组坐标
do
{
current = cursor.get();//获取当前坐标
next = current + n;//当前坐标加1就是下次要访问的数组坐标
long wrapPoint = next - bufferSize;
long cachedGatingSequence = gatingSequenceCache.get();
//如果成立,说明生产过快
if (wrapPoint > cachedGatingSequence || cachedGatingSequence > current)
{
//获取已经消费【或者准备消费的】的最小序列
long gatingSequence = Util.getMinimumSequence(gatingSequences, current);
//如果成立,说明需要等待消费者消费事件
if (wrapPoint > gatingSequence)
{
waitStrategy.signalAllWhenBlocking();//尝试唤醒消费者WorkProcessor来消费事件Event
LockSupport.parkNanos(1); // TODO, should we spin based on the wait strategy?
continue;
}
gatingSequenceCache.set(gatingSequence);
}
else if (cursor.compareAndSet(current, next))
{
break;
}
}
while (true);
return next;
}
2.run()方法分析,这个方法是多线程调用
public void run()
{
if (!running.compareAndSet(false, true))
{
throw new IllegalStateException("Thread is already running");
}
sequenceBarrier.clearAlert();
notifyStart();
boolean processedSequence = true;
long cachedAvailableSequence = Long.MIN_VALUE;
long nextSequence = sequence.get();
T event = null;
while (true)
{
try
{
// if previous sequence was processed - fetch the next sequence and set
// that we have successfully processed the previous sequence
// typically, this will be true
// this prevents the sequence getting too far forward if an exception
// is thrown from the WorkHandler
if (processedSequence)
{
processedSequence = false;
do
{
nextSequence = workSequence.get() + 1L;
sequence.set(nextSequence - 1L);
}
//两个WorkProcessor共用同一个workSequence,所以不会出现同一个事件Event被2个消费者消费
while (!workSequence.compareAndSet(nextSequence - 1L, nextSequence));
}
if (cachedAvailableSequence >= nextSequence)
{
event = ringBuffer.get(nextSequence);
workHandler.onEvent(event);
processedSequence = true;
}
else
{
//获取可以消费的最大序列
cachedAvailableSequence = sequenceBarrier.waitFor(nextSequence);
}
}
catch (final TimeoutException e)
{
notifyTimeout(sequence.get());
}
catch (final AlertException ex)
{
if (!running.get())
{
break;
}
}
catch (final Throwable ex)
{
// handle, mark as processed, unless the exception handler threw an exception
exceptionHandler.handleEventException(ex, nextSequence, event);
processedSequence = true;
}
}
notifyShutdown();
running.set(false);
}
如果没明白,看下图: