(摘自《实战Java高并发程序设计》)
Disruptor框架是由LMAX公司开发的一款高效的无锁内存队列。它使用无锁的方式实现了一个环形队列,非常适合于实现生产者和消费者模式,比如事件和消息的发布。在Disruptor中,别出心裁地使用了环形队列(RingBuffer)来代替普通线性队列,这个环形队列内部实现为一个普通的数组。对于一般的队列,势必要提供队列同步head和尾部tail两个指针,用于出队和入队,这样无疑就增加了线程协作的复杂度。但如果队列是环形的,则只需要对外提供一个当前位置cursor,利用这个指针既可以进入入队也可以进行出队操作。由于环形队列的缘故,队列的总大小必须事先指定,不能动态扩展。为了能够快速从一个序列(sequence)对应到数组的实际位置(每次有元素入队,序列就加1),Disruptor要求我们必须将数组的大小设置为2的整数次方。这样通过sequence&(queueSize-1)就能立即定位到实际的元素位置index。这个要比取余(%)操作快得多。

这种固定大小的环形队列的另外一个好处就是可以做到完全的内存复用。在系统的运行过程中,不会有新的空间需要分配或者老的空间需要回收。因此,可以大大减少系统分配空间以及回收空间的额外开销。

代码:
数据类:

public class PData {
private long value;

public void setValue(long value) {
this.value = value;
}
public long getValue() {
return value;
}
}

数据生产工厂:

public class PFactory implements EventFactory<PData> {
@Override
public PData newInstance() {
return new PData();
}
}

消费者:

public class Consumer implements WorkHandler<PData> {

@Override
public void onEvent(PData pData) throws Exception {
System.out.println("线程ID:"+Thread.currentThread().getId()+":消费了数据 "+pData.getValue());
}
}

生产者和主函数:

import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;

import java.nio.ByteBuffer;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
* @author hzy
* @date 2022-07-21
*/
public class Producer {
private final RingBuffer<PData> ringBuffer;

public Producer(RingBuffer<PData> ringBuffer) {
this.ringBuffer = ringBuffer;
}
public void pushData(ByteBuffer buffer) {
long sequence = ringBuffer.next();
try{
PData data = ringBuffer.get(sequence);
data.setValue(buffer.getLong(0));
}catch(Exception e){}
finally{
ringBuffer.publish(sequence);
}
}

public static void main(String[] args) throws InterruptedException {
Executor excutor = Executors.newCachedThreadPool();
EventFactory factory =new PFactory();
int bufferSize = 1024;
Disruptor<PData>disruptor = new Disruptor<PData>(factory,
bufferSize,
excutor,
ProducerType.MULTI,
new BlockingWaitStrategy());
disruptor.handleEventsWithWorkerPool(new Consumer(),
new Consumer(),
new Consumer(),
new Consumer());
disruptor.start();
RingBuffer<PData>ringBuffer = disruptor.getRingBuffer();
Producer producer = new Producer(ringBuffer);
ByteBuffer byteBuffer = java.nio.ByteBuffer.allocate(8);
for(long value = 0L;value < 10L;value++){
byteBuffer.putLong(0,value);
producer.pushData(byteBuffer);
Thread.sleep(10);
System.out.println("add a data"+value);
}
}
}

运行结果:

disruptor框架无锁实现生产者消费者代码实例_环形队列