《Java并发编程的艺术》——CAS(Compare and Swap)

CAS(Compare and Swap):CAS操作使用一个期望值与当前值比较,如果比较后发现相等,则用一个新值替代当前值。现可用java.util.concurrent.atomic包下的原子类使用compareAndSet()方法显示调用,实际上该包下的所有原子类的方法,基本都是CAS操作

但是CAS操作伴随着三个问题:

  • ABA问题:依照上文所说,CAS操作实际上是在检查值有没有发生变化,如果没有则更新。此时假如有一个变量原来值是A,更改为B,又更改为A,则CAS操作会认为该变量的值没有发生过修改,但是实际上是发生过了,这就发生了逻辑混乱。在Java中可以用atomic包下的AtomicStampedReference类解决ABA问题,这个类在更新值时会在值前加入一个版本号,版本戳为int类型。针对上述问题若采用了AtomicStampedReference之后,就是1A -> 1B -> 2A,就可以完美解决问题。还有一个AtomicMarkableReference类与之类似,只不过版本戳是boolean类型。
  • 自旋(循环)时间可能过长:先看一下CAS的源码,以AtomicInteger.getAndIncrement()为例,可以看到,真正的CAS操作被套在一个do-while循环里,这就意味着如果线程长时间得不到资源,就会一直循环等待,这个过程持续在占用CPU资源。
funciton getAndIncrement(){
	return unsafe.getAndAddInt();
}

function getAndAddInt(){
	...
	do{
		v = getIntVolatile();
	}while(!compareAndSwapInt());
}
  • 只能保证一个变量的原子操作,当我们要实现对多个变量的原子操作时,就只能用比如synchronized或者ReentrantLock等的悲观锁了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值