Java并发编程之CAS问题

CAS全称Compare And Swap。即比较交换。是一种轻量级锁。线程在读取数据时不进行加锁,在修改数据前,先去查询原值,操作的时候比较原值是否被修改,若未被其他线程修改则写入数据,若已经被修改,就要重新执行读取流程。CAS可以利用CAS指令和JNI完成非阻塞算法,高效的解决原子操作。但也存在三大问题。

1.ABA问题

ABA问题简单说就是一个线程a,将值A,改变成了B,然后又快速改回了A,然后另一个线程b访问该变量,发现变量值没有改变,就会误认为该变量没有被修改过的问题。那如何解决ABA问题呢?解决方法是使用版本戳。即每次变量更新的时候把版本号加1。从Java1.5开始JDK的atomic包里提供了AtomicStampedReference和AtomicMakableReference来解决ABA问题。

2.时间长开销大

自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。

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

当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁,或者有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作。

发表回复

后才能评论