java cas是原子性的么,Java面试必考问题:CAS如何保证原子性?

本文探讨了Java中CAS(Compare-and-Swap)原理,展示了如何通过JUC包的原子变量实现多线程的原子操作,以及CAS在处理器指令层面的实现。同时提到了synchronized和乐观锁策略的区别。
摘要由CSDN通过智能技术生成

前文《Java面试必考问题:如何理解volatile关键字? 》介绍了 volatile 关键字,可以保证多线程的可见性和有序性,但是不能保证原子性。要保证多线程操作的原子性,除了可以使用 synchronized 关键字,另外还可以通过CAS算法。

在JDK1.5以后的 java.util.concurrent.atomic 包(JUC)下,提供了大量的原子变量类型,包括AtomicBoolean,AtomicInteger,AtomicLong等,其内部都是使用CAS算法。

什么是CAS

CAS(Compare-and-Swap),是一种系统原语,是不可分割的操作系统指令。

CAS包含了3个操作数:

要操作的内存值 V

旧的预期值 A

要修改的新值 B

08edd3021f5a6a5dfd41b25e747ca3e4.png

CAS算法流程

当且仅当 V == A 时, 内存值更新为新值 B; 否则,不会执行任何操作。CAS更新不成功,则开始自旋,重复刚才的过程。

在整个过程中,是不需要在软件层面加锁的,这是一种乐观锁的策略。只要内存值没有发生变化,那么相信在这次修改之前,没有其它线程去动过它。synchronized锁是悲观锁策略。

CAS的底层实现

底层硬件通过将 CAS 里的多个操作在处理器指令层面上实现,通过一条处理器指令保证了原子性操作,现代多核处理器支持的原子性操作中通常都包括CAS功能。下图是CAS操作的函数调用链,我们看一下Java的CAS原子操作是如何在处理器指令层面实现的。

在IA64,x86 指令集中有 cmpxchg 指令完成 CAS 功能,在 sparc-TSO 也有 casa 指令实现,而在 ARM 和 PowerPC 架构下,则需要使用 ldrex/strex 一对指令来完成 LL/SC 的功能。

058e210e49e04aa5f0258ae55a0a34e3.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值