CAS
翻译过来是比较并交换,但他是一个原子性操作。cpu指令为 cmpxchg
CAS
CAS 有三个操作数:当前值A、内存值V、要修改的新值B
假设 当前值A 跟 内存值V 相等,那就将 内存值V 改成B
假设 当前值A 跟 内存值V 不相等,要么就重试,要么就放弃更新
将当前值与内存值进行对比,判断是否有被修改过,这就是CAS的核心
多核cpu:
举例:假如内存中v=1, 则 cpu-1 = 1,cpu-2 = 1,现在线程a将值+1变成2,则先比较内存v和 cpu-1的值是否相等,相等则将内存v更新成2
如果内存v和 cpu-1的值是否不相等,则是其他线程对该值进行了操作,则重试或者什么都不做
单核CPU:
CAS相当于没有加锁,多个线程都可以直接操作共享资源,在实际去修改的时候才去判断能否修改成功,在很多的情况下会synchronized锁要高效很多
CAS缺点
会造成ABA问题
解决方案:Java提供了AtomicStampedReference类供我们用,加了个版本,比对的就是内存值+版本是否一致
阿里巴巴开发手册 LongAdder 对象
阿里巴巴开发手册提及到 推荐使用 LongAdder 对象,比 AtomicLong 性能更好(减少乐观锁的重试次数),你能帮我解读一下吗
AtomicLong:做累加的时候实际是多个线程操作同一个资源,在高并发的时候只有一个线程可以执行成功,其他线程都会失败,不断自旋(重试),自旋会成为瓶颈