Disruptor 实现无锁队列
来源:互联网 发布:淘宝商品迁徙 编辑:程序博客网 时间:2024/06/07 20:23
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开启超线程的特性。
我不是做原理分析的! 我只是把我写的一个小例子上传上来,应用场景应该稍作修改就可以使用的!或许哪位路人需要!仅此。。。
- Disruptor 实现无锁队列
- Disruptor无锁队列浅析
- 一种高效无锁内存队列的实现(disruptor)
- Disruptor无锁ringbuff实现
- 高效内存无锁队列 Disruptor
- 致敬disruptor:CAS实现高效(伪)无锁阻塞队列实践
- disruptor:CAS实现高效(伪)无锁阻塞队列实践
- Disruptor一个开源的高效内存无锁队列
- Disruptor一个开源的高效内存无锁队列
- 无锁并发框架Disruptor
- Disruptor(无锁并发框架)
- Disruptor 高并发 无锁
- 无锁队列实现
- 无锁队列的实现
- 无锁队列的实现
- 无锁队列的实现
- 无锁队列的实现
- 无锁队列的实现
- Golang之flage
- 每个新手程序员都会犯的5个错误
- 从微软和小米的转型之痛,解读DevOps落地的核心要点
- Spring AbstractRoutingDataSource实现读写分离的Web工程
- 机器学习之KNN算法python实现
- Disruptor 实现无锁队列
- Win10彻底关闭恢复功能,终极省流量设置
- Oracle自定义函数
- Qt之Qwt初探(一)
- raft
- 数据结构
- js表单提交,支持图片上传
- Windows7+anaconda2+python3+PyCharm+TensorFlow 环境搭建(无GPU)
- java中 & | && || ^ 五种运算符的区别