Disruptor
经大佬提醒发现的一个无锁环形队列的处理高并发的一个框架Disruptor,据不完整统计 单线程一秒可以有六百万的吞吐量,都得益于RungBuffer,打破了jvm的 内存屏障 调用cpu来执行的,
这里贴上参考网站:[并发网站](http://ifeve.com/disruptor/)
[github官网](http://lmax-exchange.github.io/disruptor/)
接下来给出写的一个例子供参考一下!
1.通用得队列封装类重点内容
public class MsgEvent<T> {
/**
* 队列中实际bean
*/
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
2.队列中预分配对象内存EventFactory,事件工厂
public class MsgEventFactory<T> implements EventFactory<MsgEvent<T>>{
@Override
public MsgEvent<T> newInstance() {
return new MsgEvent<T>();
}
}
3.实体对象 Arithmetic(这里用对象的原因是更真是一点儿)
public class Arithmetic {
private long number;
public long getNumber() {
return number;
}
public void setNumber(long number) {
this.number = number;
}
public Arithmetic(long number) {
this.number = number;
}
}
4.定义消费者
public class ArithmeticHandler implements EventHandler<MsgEvent<Arithmetic>> {
@Override
public void onEvent(MsgEvent<Arithmetic> event, long arg1, boolean arg2) throws Exception {
Arithmetic at = event.getValue();
if(at.getNumber() >=6024000)//这个6024000写死了 可以更改为实际数值
{
System.out.println("消费了一个" + at.getNumber() + ***********************************************");
System.out.println(System.currentTimeMillis());
}
}
}
5.定义一个生产方法
public class ArithmeticProducer<T> {
/**
* disruptor.getRingBuffer()
*/
private final RingBuffer<MsgEvent<T>> ringBuffer;
/**
* 构造器
* @param ringBuffer disruptor.getRingBuffer()
*/
public ArithmeticProducer(RingBuffer<MsgEvent<T>> ringBuffer) {
this.ringBuffer = ringBuffer;
}
public void produce(T obj) {
long sequence = ringBuffer.next();
try {
MsgEvent<T> event = ringBuffer.get(sequence);
event.setValue(obj);
}finally{
ringBuffer.publish(sequence);
}
}
}
6.事件执行方法:
public class ArithmeticMain {
public static void main(String[] args) {
int ringBufferSize = 1024;
//Executor executor = Executors.newCachedThreadPool();
MsgEventFactory<Arithmetic> msgEventFactory = new MsgEventFactory<Arithmetic>();
Disruptor<MsgEvent<Arithmetic>> disruptor = new Disruptor<MsgEvent<Arithmetic>>(msgEventFactory, ringBufferSize,
DaemonThreadFactory.INSTANCE, ProducerType.MULTI, new YieldingWaitStrategy());
ArithmeticHandler arithmeticHandler = new ArithmeticHandler();
disruptor.handleEventsWith(arithmeticHandler);
disruptor.start();
ArithmeticProducer<Arithmetic> ar = new ArithmeticProducer<Arithmetic>(disruptor.getRingBuffer());
System.out.println(System.currentTimeMillis());
for (int i = 1; i <= 6024000; i++) {
Arithmetic a = new Arithmetic(i);
ar.produce(a);
}
}
}
这个main 中的 new YieldingWaitStrategy() 是一种等待策略
共有四种等待策略:
Disruptor 定义了 com.lmax.disruptor.WaitStrategy 接口用于抽象 Consumer 如何等待新事件,这是策略模式的应用。
Disruptor 提供了多个 WaitStrategy 的实现,每种策略都具有不同性能和优缺点,根据实际运行环境的 CPU 的硬件特点选择恰当的策略,并配合特定的 JVM 的配置参数,能够实现不同的性能提升。
例如,BlockingWaitStrategy、SleepingWaitStrategy、YieldingWaitStrategy 等,其中,
BlockingWaitStrategy 是最低效的策略,但其对CPU的消耗最小并且在各种不同部署环境中能提供更加一致的性能表现;
SleepingWaitStrategy 的性能表现跟 BlockingWaitStrategy 差不多,对 CPU 的消耗也类似,但其对生产者线程的影响最小,适合用于异步日志类似的场景;
YieldingWaitStrategy 的性能是最好的,适合用于低延迟的系统。在要求极高性能且事件处理线数小于 CPU 逻辑核心数的场景中,推荐使用此策略;例如,CPU开启超线程的特性。
我不是做原理分析的! 我只是把我写的一个小例子上传上来,应用场景应该稍作修改就可以使用的!或许哪位路人需要!仅此。。。