浅谈CAS

 

  • 为什么需要CAS机制?

为什么需要CAS机制呢?我们先从一个错误现象谈起。我们经常使用volatile关键字修饰某一个变量,表明这个变量是全局共享的一个变量,同时具有了可见性和有序性。但是却没有原子性。比如说一个常见的操作a++。这个操作其实可以细分成三个步骤:

(1)从内存中读取a

(2)对a进行加1操作

(3)将a的值重新写入内存中

 

在单线程状态下这个操作没有一点问题,但是在多线程中就会出现各种各样的问题了。因为可能一个线程对a进行了加1操作,还没来得及写入内存,其他的线程就读取了旧值。造成了线程的不安全现象。如何去解决这个问题呢?最常见的方式就是使用AtomicInteger来修饰a。我们可以看一下代码:

 

 

现在我们使用AtomicInteger类并且调用了incrementAndGet方法来对a进行自增操作。这个incrementAndGet是如何实现的呢?我们可以看一下AtomicInteger的源码。

 

 

 

到了这一步就稍微有点眉目了,原来底层调用的是compareAndSwapInt方法,这个compareAndSwapInt方法其实就是CAS机制。因此如果我们想搞清楚AtomicInteger的原子操作是如何实现的,我们就必须要把CAS机制搞清楚,这也是为什么我们需要掌握CAS机制的原因。

 

  • 分析CAS

1、基本含义

CAS全拼又叫做compareAndSwap,从名字上的意思就知道是比较交换的意思。比较交换什么呢?

过程是这样:它包含 3 个参数 CAS(V,E,N),V表示要更新变量的值,E表示预期值,N表示新值。仅当 V值等于E值时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做两个更新,则当前线程则什么都不做。最后,CAS 返回当前V的真实值。

 

CAS 操作时抱着乐观的态度进行的,它总是认为自己可以成功完成操作。所以CAS也叫作乐观锁,那什么是悲观锁呢?悲观锁就是我们之前赫赫有名的synchronized。悲观锁的思想你可以这样理解,一个线程想要去获得这个锁但是却获取不到,必须要别人释放了才可以。

 

如下图:

 

 

 

、CAS机制的优缺点

(1)优点

一开始在文中我们曾经提到过,cas是一种乐观锁,而且是一种非阻塞的轻量级的乐观锁,什么是非阻塞式的呢?其实就是一个线程想要获得锁,对方会给一个回应表示这个锁能不能获得。在资源竞争不激烈的情况下性能高,相比synchronized重量锁,synchronized会进行比较复杂的加锁,解锁和唤醒操作。

(2)缺点

缺点也是一个非常重要的知识点,因为涉及到了一个非常著名的问题,叫做ABA问题。假设一个变量 A ,修改为 B之后又修改为 A,CAS 的机制是无法察觉的,但实际上已经被修改过了。这就是ABA问题,

ABA问题会带来大量的问题,比如说数据不一致的问题等等。我们可以举一个例子来解释说明。

你有一瓶水放在桌子上,别人把这瓶水喝完了,然后重新倒上去。你再去喝的时候发现水还是跟之前一样,就误以为是刚刚那杯水。如果你知道了真相,那是别人用过了你还会再用嘛?举一个比较黄一点的例子,女朋友被别人睡过之后又换回来,还是之前的那个女朋友嘛?

 

用代码演示一下ABA的问题

 

ABA问题的解决方案:

1)添加版本号

2)AtomicStampedReference

java并发包为了解决这个问题,提供了一个带有标记的原子引用类“AtomicStampedReference”,它可以通过控制变量值的版本来保证CAS的正确性。因此,在使用CAS前要考虑清楚“ABA”问题是否会影响程序并发的正确性,如果需要解决ABA问题,改用传统的互斥同步可能会比原子类更高效。

 

 

AtomicMarkableReference:维护的是一个boolean值的标识,这种方式并不能完全防止ABA问题的发生,只能减少ABA发生的概率。

 

 

 

、CAS使用的时机

4.1 线程数较少、等待时间短可以采用自旋锁进行CAS尝试拿锁,较于synchronized高效

4.2 线程数较大、等待时间长,不建议使用自旋锁,占用CPU较高

 

五、Unsafe类

是CAS的核心类,由于java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据

Unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为Java中CAS操作执行依赖于Unsafe类

Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务 

 

猜你喜欢

转载自blog.csdn.net/huzhiliayanghao/article/details/106556804
Cas