CAS是什么?Atomic包知多少?

JDK1.5中增加的一个最主要的支持是Atomic类,如AtomicInteger、AtomicLong等,这些类可帮助最大限度地减少在多线程中对于一些基本操作(例如,增加或减少多个线程之间共享的值)的复杂性,而这些类的实现都依赖于CAS(compare and swap)的算法。

一、CAS

1.CAS原理

CAS的全称是Compare And Swap——比较交换,CAS中有三个核心参数:

  • 主内存中存放的V值,所有线程共享。
  • 线程上次从内存中读取的V值A存放在线程的帧栈中,每个线程私有。
  • 需要写入内存中并改写V值的B值。也就是线程对A值操作后放入到主存V中。
CAS是什么?Atomic包知多少?_第1张图片

CAS的核心是在将B值写入到V之前要比较A值和V值是否相同,如果不相同证明此时V值已经被其他线程改变,重新将V值赋给A,并重新计算得到B,如果相同,则将B值赋给V。

CAS是一种乐观锁,当多个线程同时使用CAS操作一个变量时,只有一个会胜出,并成功更新,其余均会失败,但失败的线程并不会被挂起,仅是被告知失败,并且允许再次尝试,直到成功为止(JDK代码中采用while循环不断自旋)。由于无锁,因此不可能出现死锁的情况,也就是说无锁操作天生免疫死锁。

source: 全面了解Java中的CAS机制

2.CAS的优劣

cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时间片之间,需要进行cpu切换,也就是会发生进程的切换。如果采用悲观锁(如Sychronizied独占锁),在进程挂起和恢复执行过程中存在着很大的开销,同时当一个线程正在等待锁时,它不能做任何事。用乐观锁在读多写少的场景下,性能就会比较优越。

CAS之不足:

  • 循环时间长开销很大:如果CAS失败,会一直进行尝试。如果CAS长时间一直不成功,可能会给CPU带来很大的开销。

  • 只能保证一个共享变量的原子操作:当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁来保证原子性。

  • ABA问题
    如果一开始位置V得到的旧值是A,当进行赋值操作时再次读取发现仍然是A,并不能说明变量没有被其它线程改变过。有可能是其它线程将变量改为了B,后来又改回了A。大部分情况下ABA问题不会影响程序并发的正确性,如果要解决ABA问题,可以用传统的互斥同步。Java并发包为了解决这个问题,提供了一个带有标记的原子引用类AtomicStampedReference,它可以通过控制变量值的版本来保证CAS的正确性。

source: 面试必问的CAS,你懂了吗

二、Atomic原子包

原子更新基本类型主要包括3个类:

  • AtomicBoolean:原子更新布尔类型
  • AtomicInteger:原子更新整型
  • AtomicLong:原子更新长整型

这3个类的实现原理和使用方式几乎是一样的,提供了原子自增方法、原子自减方法以及原子赋值方法等。原子类的内部几乎是基于Unsafe类中的CAS相关操作的方法实现的,这也同时证明其是基于无锁实现的。Unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为Java中CAS操作的执行依赖于Unsafe类的方法,注意Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务。

//JDK 1.7的源码,由for的死循环实现,并且直接在AtomicInteger实现该方法,
//JDK1.8后,该方法实现已移动到Unsafe类中,直接调用getAndAddInt方法即可
public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }

source:JAVA中的CAS

三、Volatile与自旋操作


CAS自旋volatile变量,是一种很经典的用法。volatile 关键字不具有原子性,但是具有可见性和有序性,volatile 关键字由于不会引起线程上下文切换和调度,在只需要保证 可见性 或者 有序性 时,可以使用 volatile 关键字,提升性能,尤其是在CAS。

source :volatile和CAS

你可能感兴趣的:(CAS是什么?Atomic包知多少?)