原文:http://blog.codeaholics.org/2011/the-disruptor-lock-free-publishing/

译者:罗立树

假如你生活在另外一个星球,我们最近开源了一套高性能的基于消息传递的开源框架。

下面我给大家介绍一下如何将消息通过Ring buffer在无锁的情况下进行处理。

在深入介绍之前,可以先快速阅读一下Trish发表的文章,该文章介绍了ring buffer和其工作原理。

这篇文章的要点如下:

1.ring buffer是由一个大数组组成的。

2.所有ring buffer的“指针”(也称为序列或游标)是java long类型的(64位有符号数),指针采用往上计数自增的方式。(不用担心越界,即使每秒1,000,000条消息,也要消耗300,000年才可以用完)。

3.对ring buffer中的指针进行按ring buffer的size取模找出数组的下标来定位入口(类似于HashMap的entry)。为了提高性能,我们通常将ring buffer的size大小设置成实际使用的2倍。

这样我们可以通过位运算(bit-mask )的方式计算出数组的下标。

Ring buffer的基础结构

注意:和代码中的实际实现,我这里描述的内容是进行了简化和抽象的。从概念上讲,我认为更加方面理解。

ring buffer维护两个指针,“next”和“cursor”。

在上面的图示里,是一个size为7的ring buffer(你应该知道这个手工绘制的图示的原理),从0-2的坐标位置是填充了数据的。

“next”指针指向第一个未填充数据的区块。“cursor”指针指向最后一个填充了数据的区块。在一个空闲的ring bufer中,它们是彼此紧邻的,如上图所示。

填充数据(Claiming a slot,获取区块)

Disruptor API 提供了事务操作的支持。当从ring buffer获取到区块,先是往区块中写入数据,然后再进行提交的操作。

假设有一个线程负责将字母“D”写进ring buffer中。将会从ring buffer中获取一个区块(slot),这个操作是一个基于CAS的“get-and-increment”操作,将“next”指针进行自增。这样,当前线程(我们可以叫做线程D)进行了get-and-increment操作后,

指向了位置4,然后返回3。这样,线程D就获得了位置3的操作权限。

接着,另一个线程E做类似以上的操作。

提交写入

以上,线程D和线程E都可以同时线程安全的往各自负责的区块(或位置,slots)写入数据。但是,我们可以讨论一下线程E先完成任务的场景…

线程E尝试提交写入数据。在一个繁忙的循环中有若干的CAS提交操作。线程E持有位置4,它将会做一个CAS的waiting操作,直到  “cursor”变成3,然后将“cursor”变成4。

再次强调,这是一个原子性的操作。因此,现在的ring buffer中,“cursor”现在是2,线程E将会进入长期等待并重试操作,直到 “cursor”变成3。

然后,线程D开始提交。线程E用CAS操作将“cursor”设置为3(线程E持有的区块位置)当且仅当“cursor”位置是2.“cursor”当前是2,所以CAS操作成功和提交也成功了。

这时候,“cursor”已经更新成3,然后所有和3相关的数据变成可读。

这是一个关键点。知道ring buffer填充了多少 – 即写了多少数据,那一个序列数写入最高等等,是游标的一些简单的功能。“next”指针是为了保证写入的事务特性。

最后的疑惑是线程E的写入可见,线程E一直重试,尝试将“cursor”从3更新成4,经过线程D操作后已经更新成3,那么下一次重试就可以成功了。

总结

写入数据可见的先后顺序是由线程所抢占的位置的先后顺序决定的,而不是由它的提交先后决定的。但你可以想象这些线程从网络层中获取消息,这是和消息按照时间到达的先后顺序是没什么不同的,而两个线程竞争获取一个不同循序的位置。

因此,这是一个简单而优雅的算法,写操作是原子的,事务性和无锁,即使有多个写入线程。

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: Disruptor(无锁并发框架)-发布

Disruptor(无锁并发框架)-发布相关推荐

  1. java 无锁框架_高性能无锁并发框架 Disruptor,太强了!

    Java技术栈 www.javastack.cn 关注优质文章 Disruptor是一个开源框架,研发的初衷是为了解决高并发下队列锁的问题,最早由LMAX提出并使用,能够在无锁的情况下实现队列的并发操 ...

  2. 【java并发编程】无锁并发框架disruptor

    一.简介 Disruptor是一个高性能队列,研发的初衷是解决内部的内存队列的延迟问题,而不是分布式队列.基于Disruptor开发的系统单线程能支撑每秒600万订单. 使用场景:对延时要求很高的场景 ...

  3. Java无锁并发详细教程

    问题提出 有如下需求,保证 account.withdraw 取款方法的线程安全 package cn.itcast;import java.util.ArrayList; import java.u ...

  4. 每秒钟承载600万订单级别的无锁并行计算框架 Disruptor学习

    1.来源 Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内部的内存队列的延迟问题,而不是分布式队列.基于Disruptor开发的系统单线程能支撑每秒600万订单,2 ...

  5. Disruptor无锁ringbuff实现

    http://blog.163.com/zongyuan1987@126/blog/static/131623156201271021955717/?latestBlog Disruptor是LMAX ...

  6. 无锁并发的CAS为何如此优秀?

    Talk is cheap CAS(Compare And Swap),即比较并交换.是解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数--内存位置(V).预期原值(A)和新 ...

  7. java无锁消费者框架_无锁并行框架多生产者多消费者模型

    下面看一下多生产多消费者的模式,下面的代码是模拟100个生产者,每个生产者生产100个事件,然后有3个消费者,同时进行消费,共消费1W个事件, 下面看一下代码: 这边new出了3个消费者,并把消费者数 ...

  8. Java并发编程,无锁CAS与Unsafe类及其并发包Atomic

    为什么80%的码农都做不了架构师?>>>    我们曾经详谈过有锁并发的典型代表synchronized关键字,通过该关键字可以控制并发执行过程中有且只有一个线程可以访问共享资源,其 ...

  9. Java并发编程-无锁CAS与Unsafe类及其并发包Atomic

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772470 出自[zejian ...

  10. 学习笔记:Java 并发编程④_无锁

    若文章内容或图片失效,请留言反馈. 部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 视频链接:https://www.bilibili.com/video/av81461839 配套资料: ...

最新文章

  1. 写作预报之Hyper-V Server的图形化管理系统配置!
  2. 呼叫中心如何规划好工作习惯
  3. 产品经理第一课上海站圆满结束,下一站你定!
  4. @EnableCaching与@Cacheable的使用方法,结合redis进行说明
  5. jquery之图片懒加载(总结)
  6. AtomicStampedReference
  7. 特例模式(Special Case Pattern)与空对象模式(Null Pointer Pattern)—— 返回特例对象而非 null
  8. 如何取得GridView被隐藏列的值
  9. CUBA Platform 7.0.3 发布,企业级应用开发平台
  10. matlab颜色选取与绘制?(附有颜色全表)
  11. 霍尔传感器学习使用心得
  12. Win11 mscorsvw程序大量占用内存的解决方法
  13. 阅读笔记--计算机网络 自顶向下方法
  14. 对帧率、I/P率、I帧间隔的理解2021-11-16
  15. JS 基础知识点与高频考题解析
  16. 视频教程-Echarts+Asp.Net+Sql Server报表开发视频教程-.NET
  17. 漫谈OCL概念、特征和实践(作者:大雁北飞)
  18. SQL中UNPIVOT是什么
  19. 使用memccpy函数替代不安全的str[n]cpy、str[n]cat等
  20. JAVA计算机毕业设计新疆旅游专列订票系统Mybatis+源码+数据库+lw文档+系统+调试部署

热门文章

  1. 丢失控制文件恢复实验记录--4(在线日志文件没有损坏,归档日志丢失,直接重建控制文件(跟踪控制文件trace是旧的情况))...
  2. vue项目开发之v-for列表渲染的坑
  3. python: excel单元格读取写入
  4. 第一章数据结构和算法简介
  5. 【2012.1.24更新】不要再在网上搜索eclipse的汉化包了!
  6. 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常...
  7. 防止xss(脚本攻击)的方法之过滤器
  8. 【原创】洛谷 LUOGU P3371 【模板】单源最短路径
  9. HTML5的绘画支持(五)
  10. 怎么去掉word标题前的黑点