CAS

简介: 一、CAS简介CAS是原子类的底层原理,同时也是乐观锁的原理,CAS全称Compare-And-Swap,中文含义“比较并交换”,它是一种思想,一种算法。特点,避免使用互斥锁,当多个线程同时使用CAS更新同一个变量时,在多线程的情况下,为了保证并发的安全性,我们可以使用互斥锁,而CAS的特点是避免使用互斥锁,当多个线程同时使用CAS更新同一个变量时,只有其中一个线程能够操作成功,而其他线程都会更新失败。不过和同步互斥锁不同的是,CAS不会让失败的线程阻塞,而是被告知这次由于竞争而导致的操作失败,但还可以再次尝试。

一、CAS简介

CAS是原子类的底层原理,同时也是乐观锁的原理,CAS全称Compare-And-Swap,中文含义“比较并交换”,它是一种思想,一种算法。

特点,避免使用互斥锁,

当多个线程同时使用CAS更新同一个变量时,

在多线程的情况下,为了保证并发的安全性,我们可以使用互斥锁,而CAS的特点是避免使用互斥锁,当多个线程同时使用CAS更新同一个变量时,只有其中一个线程能够操作成功,而其他线程都会更新失败。不过和同步互斥锁不同的是,CAS不会让失败的线程阻塞,而是被告知这次由于竞争而导致的操作失败,但还可以再次尝试。

CAS广泛用在并发编程领域中,以实现那些不会被打断的数据交换操作,从而实现无锁的安全。

CAS思路

CAS核心思路是,当前的内存值V,预期值A,要修改的值B,仅当当前的内存值V和A值相同时,才将内存值修改为B。

CAS会提前假定当前内存值V应该等于值A。而值A往往是之前读取到当时的内存值V,在执行CAS时,如果发现当前的内存值V恰好是值A的话,CAS就会把内存值V改变成值B。而值B往往是在拿到值A后,在值A的基础上经过计算而得到的。

如果执行CAS时发现此时内存值V不等于值A,则说明在刚才计算B的期间内,内存值已经被其他线程改过了,那么本次CAS就不应该再修改了。可以避免多人同时修改导致出错。

CAS实现的是无锁算法是写上机制,

互斥锁不存在写上机制,大家都会尝试抢占资源,利用CAS和利用互斥锁都已保证并发安全。是实现相同目标的不同手段。

例如:

CPU1 内存值V是100, 假设有两个线程,分别使用CPU,他们都是利用CAS来改变右边的变量的值。我们先看线程1,它使用CPU1,假设它先执行,它期望当前的值是100,并且想将100,修改为150,在执行的时候,它会去检查当前的值是不是100,发现真的是100,所以可以改动成功,而当改完之后,右边的值就会变为150。

CPU2,内存值V是150,线程2,它使用CPU2,假设它来执行,它想把这个值从100,改为200,但是发现预期值和内存地址不一致,所以修改失败。

CAS等价语义的代码

/**
 * 描述:     模拟CAS操作,等价代码
 */
 
public class SimulatedCAS {
 
    private int value;
 
    public synchronized int compareAndSwap(int expectedValue, int newValue) {
        int oldValue = value;
        //这一行就说明 期望的A值等于 内存值V,就改把V该成B值。
        if (oldValue == expectedValue) {
            value = newValue;
        }
        return oldValue;
    }
}

两个线程竞争CAS的,一个线程改变了值,另一个线程就不会再改变值了。

二、CAS的和乐观锁的关系,什么时候会用到CAS?

在并发容器中的应用

ConcurrentHashMap中使用了

ConcurrentLinkedQueue

在数据库中的应用

数据库中也存在对乐观锁和CAS思想的应用

更新数据时,可以利用version字段在数据库中实现乐观锁和CAS操作,而在获取和修改数据时都不需要加悲观锁

在原子类中的应用

在原子类中,例如AtomicInteger,也是使用了CAS,AtomicInteger的getAndAdd方法。

三、CAS的缺点

优点是避免使用互斥锁,使性能更高。

1、但是它的缺点是ABA问题,A变成B,又变成A。CAS检查的是并不是值没有发生变化,而是去比较这当前的值和预期值是不是相等。

在变量值自身之外,再添加一个版本号,这个值的变化路径就从A->B->A变成了1A->2B-3A。通过这样的思路就可以解决ABA的问题。

2、自旋的时间过长,如果应用场景本身就是高并发的场景,就有可能导致CAS一直都操作不成功,循环时间就会越来越长,根据实际情况是否使用CAS,在高并发的场景下,通常CAS的效率是不高的。

3、不能灵活的控制范围。

通常我们执行CAS时,是针对某一个,而不是多个共享变量,这个变量可能是Integer类型,也有可能是Long类型、对象类型。

如果想对多个对象同时进行CAS操作,是比较困难的。解决方法就是,利用一个新的类,整合刚才这一组共享变量。

目录
相关文章
|
存储 编译器 API
锁与原子操作CAS
锁与原子操作CAS
148 0
|
存储 资源调度 安全
H3C CAS系列 一、CAS初认识
对于虚拟化,可能第一时间大家想到的是虚拟机,而对于虚拟机大家可能第一时间想到的就是我们大多数人都可能比较熟悉的VMware系列产品,比如常用VMware Workstation Pro 、VMware esxi。 而今天我带大家一起认识一款我们国产的虚拟化软件 H3C CAS。
1770 0
|
6月前
|
算法 调度 数据安全/隐私保护
什么是CAS锁
什么是CAS锁
79 0
|
6月前
|
Java API
CAS的超~详细介绍
CAS的超~详细介绍
|
6月前
|
算法
原子操作CAS
原子操作CAS
40 0
|
6月前
|
缓存 Linux API
原子操作CAS与锁实现
原子操作CAS与锁实现
|
6月前
|
存储 缓存 算法
理解原子操作与CAS锁
理解原子操作与CAS锁
81 0
|
6月前
|
算法 Java 关系型数据库
CAS
本文主要讲解java中cas的概念及原理
63 0
什么是 CAS? CAS 有哪些缺点?ABA 问题是什么?
什么是 CAS? CAS 有哪些缺点?ABA 问题是什么?
197 0