一、什么是 CAS
CAS 全程 Compare-And-Swap,它的功能是判断内存中某个位置的值是否为预期值,如果是则更改为新值,这个过程是原子性的。
二、CAS 作用
CAS 是另一个无锁解决方案,更准确的是采用乐观锁技术,实现线程安全的问题。
三、CAS 实现原理
在设计思想上,CAS 的执行有三个操作数,V-内存值,A-期望值,B-修改成的目标值。当且仅当 V 的值等于 A 时, CAS 通过原子方式用新值 B 来更新 V 的值,否则不会执行任何操作。
CAS 是一条CPU 并发原语。即属于操作系统用语范畴,是由若干条指令组成,用于完成某种功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许被中断。
JAVA 中的 CAS 操作通过调用 sun.misc.Unsafe 类中各个方法来实现。当调用 UnSafe 类中的 CAS 方法,JVM 会帮我们实现出 CAS 汇编指令。这是一种完全依赖与硬件的功能,通过它实现了原子操作。
四、实战演练
在 java.util.concurrent.atomic 包下提供了很多 AtomicXXX 原子性操作的类,它们底层封装了 UnSafe 类来提供 CAS 操作相关的方法,我们以 AtomicInteger 为例,执行 1000 的数字累加操作:
1 | public class CASTest { |
执行结果:
1 | number: 972 |
案例中,我们声明了普通的静态变量 number 和原子类型的 atomicNumber,让它们在多线程下各执行 1000 次的数值累加。
由于 number ++ 编译成字节码是多行指令,并非原子操作,当多线程访问修改时,大概率有旧值覆盖新值的问题,因此出现累加 1000 次的操作后结果却小于 1000 的情况。
而 atomicNumber.incrementAndGet() 底层使用了 CAS,确保数值修改的原子性,因此能正常返回结果。