Java中的CAS及其缺陷

Java中的CAS

CAS

CAS全称是Compare-and-Swap,翻译中文是比较并交换,是并发编程中一种常用的算法。Java中concurrent包完全建立在CAS上。我们常见并发控制是使用锁,这是一种悲观的策略,假设每次对资源访问都会发生冲突,所以当有一个线程访问资源时,其他线程就必须等待。与之相反的时乐观的策略,假设线程对资源的访问是没有冲突的,同是所有线程执行都不需要等待,如果遇到冲突,就会使用CAS来鉴别冲突,如果鉴别到冲突,就重试当前操作直到没有冲突为止。

CAS的大概执行步骤:

  • 1、读取内存中某个变量的值为一个临时变量;
  • 2、对内存中某个变量的值进行一系列操作;
  • 3、判断临时值与内存中某个变量的值是否相等,如果相等则没有别修改过,那么将上面步骤2的操作结果写入;不相等则是被其他线程修改过,此时放弃或者从步骤1开始重试。

步骤3就是比较替换,这个步骤是需要原子性,不然无法保证比较操作之后其它线程的影响。

Unsafe

Java中无法直接访问底层操作系统,必须通过本地方法(Native)来进行访问。即提供了Unsafe类,该类里面提供了大量Native方法,来支持硬件级别的原子操作。尽管这个类里卖弄的方法都是public的,但是我们不能使用它,官方也不建议我们使用。

这是Unsafe类中CAS操作相关的方法:

	public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);

    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

    public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

更多关于Unsafe类的知识自行查阅资料。

CAS的缺点
  • ABA问题

    CAS操作的时候需要检查值有没有发生改变,但是如果有两个线程1、2对变量V进行操作,线程2获取的获取的变量V的值是A,但是线程1将V的值先修改为B,后面又修改为A,此时线程2去更新时比较变量V的值还是A,所以线程2发现值没有改变,但实际上值发生了改变。

  • 循环时间开销

    重试长时间不成功,会给CPU带来非常大的执行开销。

  • 只能保证一个共享变量的原子操作

    Java中CAS操作只是对CPU指令的一层封装,一次只能原子操作一个变量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值