Java并发编程(三)—CAS的原理及应用场景

目录

1、CAS的原理

2、CAS的问题

1)ABA问题

2)自旋锁消耗问题

3)多变量共享一致性问题

4)不可中断性

3、CAS的应用

4、总结


1、CAS的原理

CAScompare and swap比较与交换,是一种乐观锁机制,也叫无锁机制。即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)

CAS 中涉及三个要素:

  • 需要读写的内存值 V

  • 进行比较的值 A

  • 拟写入的新值 B

当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做

CAS的原子性

CAS操作是原子的,这意味着它要么完全执行成功,要么完全不执行。即使在多线程环境中,也不会有其他线程能够干扰CAS操作的执行

在之前文章Java并发—volatile关键字的作用及使用场景-CSDN博客中使用了volatile关键字修改变量x的过程,但修改和写回操作不是原子性,还是会有数据不一致性的问题,CAS就可以解决这个问题,那使用CAS操作来修改共享变量x,流程又会是如何呢?


还是使用之前的案例:🌰线程A和线程B从主内存读取和修改x=1的过程

步骤:

        1.初始化:x=1,存储在主内存

        2.线程A读取:A从主内存读取,复制x=1到A的工作内存

        3.线程B读取:B从主内存读取x,复制x=1到B的工作内存

        4.线程A修改:A在工作内存中修改x=2

        5.线程A尝试CAS写回:A将工作内存中的x=2与主内存中的x=1进行比较

                如果主内存中仍然是x=1(预期值),则CAS操作成功,x=1更新至x=2

                如果主内存中x≠1(被其他线程修改),则CAS操作失败,线程A需要重新读取更新的值并再次尝试重新读取最新的值

        6.线程B修改:B在工作内存中修改x=3

        7.线程B尝试CAS写回

                如果主内存中x=1(这是B读取时的值,但此时可能已经被A修改x=2),也就是线程B以为主内存中是x=1(预期值),但实际上主内存是x=2(实际值),预期值与实际值不符,则 CAS操作失败          

                B需要重新读取最新的值x=2,并尝试CAS操作

        8.线程B重新读取:x=2

        9.线程B再次尝试CAS写回:B再次尝试将x=2更新至x=3,如果此时没有其他线程修改x,则CAS操作成功

由上述流程可以看出当使用CAS操作来修改共享变量x时,与volatile修改共享变量x流程会有所不同,CAS也成功得解决了上一篇文章中遗留问题


2、CAS的问题

看起来好像又没问题了,但CAS会出现ABA问题

1)ABA问题

什么是ABA问题呢?

ABA 问题说的是,如果一个变量第一次读取的值是 A,准备好需要对 A 进行写操作的时候,发现值还是 A,那么这种情况下,能认为 A 的值没有被改变过吗?可以是由 A -> B -> A 的这种情况

那如何解决呢?

为了解决ABA问题,常见的做法是在CAS操作中加入版本号标记。例如,可以使用 AtomicStampe

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值