消息队列高手课
李玥
京东零售技术架构部资深架构师
立即订阅
8426 人已学习
课程目录
已完结 41 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (2讲)
开篇词 | 优秀的程序员,你的技术栈中不能只有“增删改查”
免费
预习 | 怎样更好地学习这门课?
基础篇 (8讲)
01 | 为什么需要消息队列?
02 | 该如何选择消息队列?
03 | 消息模型:主题和队列有什么区别?
04 | 如何利用事务消息实现分布式事务?
05 | 如何确保消息不会丢失?
06 | 如何处理消费过程中的重复消息?
07 | 消息积压了该如何处理?
08 | 答疑解惑(一) : 网关如何接收服务端的秒杀结果?
进阶篇 (21讲)
09 | 学习开源代码该如何入手?
10 | 如何使用异步设计提升系统性能?
11 | 如何实现高性能的异步网络传输?
12 | 序列化与反序列化:如何通过网络传输结构化的数据?
13 | 传输协议:应用程序之间对话的语言
14 | 内存管理:如何避免内存溢出和频繁的垃圾回收?
加餐 | JMQ的Broker是如何异步处理消息的?
15 | Kafka如何实现高性能IO?
16 | 缓存策略:如何使用缓存来减少磁盘IO?
17 | 如何正确使用锁保护共享数据,协调异步线程?
18 | 如何用硬件同步原语(CAS)替代锁?
19 | 数据压缩:时间换空间的游戏
20 | RocketMQ Producer源码分析:消息生产的实现过程
21 | Kafka Consumer源码分析:消息消费的实现过程
22 | Kafka和RocketMQ的消息复制实现的差异点在哪?
23 | RocketMQ客户端如何在集群中找到正确的节点?
24 | Kafka的协调服务ZooKeeper:实现分布式系统的“瑞士军刀”
25 | RocketMQ与Kafka中如何实现事务?
26 | MQTT协议:如何支持海量的在线IoT设备?
27 | Pulsar的存储计算分离设计:全新的消息队列设计思路
28 | 答疑解惑(二):我的100元哪儿去了?
案例篇 (7讲)
29 | 流计算与消息(一):通过Flink理解流计算的原理
30 | 流计算与消息(二):在流计算中使用Kafka链接计算任务
31 | 动手实现一个简单的RPC框架(一):原理和程序的结构
32 | 动手实现一个简单的RPC框架(二):通信与序列化
33 | 动手实现一个简单的RPC框架(三):客户端
34 | 动手实现一个简单的RPC框架(四):服务端
35 | 答疑解惑(三):主流消息队列都是如何存储消息的?
测试篇 (2讲)
期中测试丨10个消息队列热点问题自测
免费
期末测试 | 消息队列100分试卷等你来挑战!
结束语 (1讲)
结束语 | 程序员如何构建知识体系?
消息队列高手课
登录|注册

18 | 如何用硬件同步原语(CAS)替代锁?

李玥 2019-09-03
你好,我是李玥。上节课,我们一起学习了如何使用锁来保护共享资源,你也了解到,使用锁是有一定性能损失的,并且,如果发生了过多的锁等待,将会非常影响程序的性能。
在一些特定的情况下,我们可以使用硬件同步原语来替代锁,可以保证和锁一样的数据安全性,同时具有更好的性能。
在今年的 NSDI(NSDI 是 USENIX 组织开办的关于网络系统设计的著名学术会议)上,伯克利大学发表了一篇论文《Confluo: Distributed Monitoring and Diagnosis Stack for High-speed Networks》,这个论文中提到的 Confluo,也是一个类似于消息队列的流数据存储,它的吞吐量号称是 Kafka 的 4~10 倍。对于这个实验结论我个人不是很认同,因为它设计的实验条件对 Kafka 来说不太公平。但不可否认的是,Confluo 它的这个设计思路是一个创新,并且实际上它的性能也非常好。
Confluo 是如何做到这么高的吞吐量的呢?这里面非常重要的一个创新的设计就是,它使用硬件同步原语来代替锁,在一个日志上(你可以理解为消息队列中的一个队列或者分区),保证严格顺序的前提下,实现了多线程并发写入。
今天,我们就来学习一下,如何用硬件同步原语(CAS)替代锁?
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《消息队列高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(27)

  • 微微一笑
    老师好,实现了下CAS,代码连接:https://github.com/shenyachen/JKSJ/blob/master/study/src/main/java/com/jksj/study/casAndFaa/CASThread.java。
    对于FAA,通过查找资料,jdk1.8在调用sun.misc.Unsafe#getAndAddInt方法时,会根据系统底层是否支持FAA,来决定是使用FAA还是CAS。

    作者回复: 👍👍👍

    2019-09-03
    7
  • 一步
    NodeJS中,没有发现有关操作CpU原语CAS或者FAA的实现的

    作者回复: 可以试试这个:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics

    2019-09-03
    1
    5
  • 姜戈
    JAVA中的FAA和CAS: FAA就是用CAS实现的。

    public final int getAndAddInt(Object var1, long var2, int var4) {
            int var5;
            do {
                var5 = this.getIntVolatile(var1, var2);
            } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

            return var5;
        }
    2019-09-03
    4
  • QQ怪
    MutxLock:https://github.com/xqq1994/algorithm/blob/master/src/main/java/com/test/concurrency/MutxLock.java
    CAS、FFA:
    https://github.com/xqq1994/algorithm/blob/master/src/main/java/com/test/concurrency/CAS.java
    完成了老师的作业,好高兴

    作者回复: 👍👍👍

    2019-09-03
    2
  • 张三
    复习了一下Java中的原子类,对应到go里边的CAS实现中的for循环是自旋,还有就是要注意ABA问题吧。
    2019-09-03
    2
  • Switch
    java实现, 锁、Unsafe类、AtomicInteger类

    https://github.com/Switch-vov/mq-learing/tree/master/src/main/java/com/switchvov/transfer
    2019-10-25
    1
  • 顶新
    .net 实现代码:
    lock 实现:
    static void transfer(object amount)
            {
                lock (obj)
                {
                    balance = balance + Convert.ToInt32(amount);
                }
            }
    cas 实现:
    static void transfer_cas(object amount)
            {
                int initialValue, computedValue;
                do
                {
                    initialValue = balance;
                    computedValue = initialValue + Convert.ToInt32(amount);
                } while (initialValue != Interlocked.CompareExchange(
                    ref balance, computedValue, initialValue));
            }

    faa 实现:
    static void transfer_faa(object amount){
                Interlocked.Add(ref balance,Convert.ToInt32(amount));
            }
    2019-09-23
    1
  • 明日
    Java实现: https://gist.github.com/imgaoxin/a2b09715af99b993e30b44963cebc530

    作者回复: transfer2要放在循环中,否则有可能转账失败。
    另外,transfer1中,虽然一个简单的加法不会引起任何异常,但总是把unlock放到finnally中是一个好习惯。

    2019-09-03
    1
  • leslie
    打卡:老师一步步剥离一层层拨开实质-又涨知识了,期待老师的下节课。
    2019-09-03
    1
  • 张三
    Java里边有支持FAA这种CPU指令的实现吗?以前没听说

    作者回复: 在java中,可以看一下java.util.concurrent.atomic.AtomicLong#getAndAdd

    2019-09-03
    1
    1
  • Sicily9
    有一个小疑问,关于原子性的话,有一个极端情况,多核并行情况下 两个线程 同时在执行一个cas原语 会有安全问题吗

    作者回复: 不会的,可以放心使用。

    2019-11-19
    1
  • PeterLu
    交作业:https://github.com/PeterLu798/MQ/tree/master/src/com/lbj/mq/lock
    LockBalance.java使用Java独占锁实现,平均耗时 300毫秒左右
    CASBalance.java使用AtomicInteger实现,平均耗时250毫秒左右
    2019-10-30
  • 达文西
    cas需要注意 aba 问题吧
    2019-10-10
  • 长期规划
    Python没找到CAS和FAA的实现

    作者回复: CPython(就是我们最常用的Python)中确实没有提供原子操作。可以看一下pypy:https://pypy.org/

    2019-10-09
  • godtrue
    之前只知CAS,还有FAA,想必应该有一坨类似的原语。打卡,感谢,又增长了一点见识。
    2019-09-24
  • 王莹
    代码工程
    https://github.com/dlutsniper/wy-ja-lock/tree/master/src/main/java/wy/ja/lock/demo
    试验耗时的环节,深刻体会JIT的强大,执行次数越多,耗时均值越低
    JIT吗?执行越多速度越快?
    关闭JIT -Xint / -Djava.compiler=NONE
    AccountDemoSynchronized 100次关闭前后
      开启 16.66ms 13.77ms 11.26ms
      关闭 93.14ms 102.12ms 81.13ms
    AccountDemoCas 100次关闭前后
      开启 12.74ms 10.5ms 12.42ms
      关闭 82.48ms 74.7ms 77.09ms
    2019-09-09
  • 青舟
    https://github.com/qingzhou413/geektime-mq.git
    做了1000万次加法,
    Lock: 380ms
    CAS: 200ms
    FAA: 280ms

    作者回复: java里面有AtomicInteger等等封装好的类,包含了CAS和FAA等原子操作,可以直接使用的。

    2019-09-04
    1
  • Randy Liu
    用户硬件同步原语来代替锁的效果,确实是一个好思路
    2019-09-04
  • 许童童
    老师讲得很好,对于我这种基础薄弱的,长见识了,感谢老师。
    2019-09-03
  • 潘政宇
    go的语法太奇特了,代码中的done作用是什么啊

    作者回复: 可以参考一下:https://blog.golang.org/pipelines

    2019-09-03
收起评论
27
返回
顶部