并发 - CAS 随手记

并发 - CAS 随手记

前言

CAS是在JUC中,已经无处不在了,看过JUC源码的小伙伴可能都知道,原子操作类,一大堆,
不废话了,cas是一种无状态锁,即比较交换。

一、原理

一句话理解,复制拷贝,简单说,就是比较内存值和旧拷贝值,如果两者相等就 就把我们新的预期值给到内存值,就完了。

有啥缺点:
1.存在ABA问题,即线程1获取变量值为5,线程2将值改为10,线程3再将值改回5,那么对于1线程来说,是发现不了值变化过了。
ABA问题,可以通过加版本号,或者加时间戳的方式解决,如JUC并发包下AtomicMarkableReference 使用了boolean变量 ——表示引用变量是否被更改过,不关心中间变量变化了几次。
AtomicStampedReference通过用其中的构造方法中initialStamp(时间戳)用来唯一标识引用变量,引用变量中途被更改了几次,以此解决ABA问题。

2.还有一个比较深的问题,简单提一下
Cache miss问题,简单说,操作系统内存机制带来的问题,内存数据,要有缓存线概念,高速度缓存需要从缓存线中拿,比如CPU0 在对一个变量执行“比较并交换”(CAS)操作,而该变量所在的缓存线在 CPU7 的高速缓存中,这样就需要一个个个去找了。

3 长时间自旋带来的性能消耗
以JUC下AtomicLong为例,高并发场景下,假如线程一直无法进行CAS操作成功,内部是dowhile死循环,会一直自旋,消耗CPU。

提提Unsafe类
Unsafe是CAS核心类。我们知道,Java是无法直接访问底层操作系统,而是通过本地方法访问。JDK中Unsafe类,底层调用本地方法,提供硬件级别原子操作。
可以使用sun.misc.Unsafe包下。
Unsafe unsafe = Unsafe.getUnsafe();
调用部分方法
也可以通过反射获取Unsafe实例。

Field field = Unsafe.class.getDeclareField(“theUnsafe”);
field.setAccessible(true);
获取

还有其他的很多方式,工具类,不细说啦

热爱生活的码小子wmxiang:
工作之余,记录自己平时的一些小毛病,以及问题排查和解决方案思路。记录自己的经验和不足之处,笔记中可能会有很多不足之处,欢迎各位留言指正讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值