【多线程】详解 CAS 机制-1. CAS 是什么

CAS】全称为 Compare and swap,即"比较并交换",相当于通过一个原子操作,同时完成"读取内存,比较是否相等,修改内存"这三个步骤,本质上需要 CPU 指令支持~

CAS 是并发编程中一个重要的概念,相当于是打开了新世界的大门,可以在不加锁的情况下保证线程安全,从而减少线程之间的竞争和开销,通常用于无锁编程,本文将结合 Java 多线程操作讲解 CAS 机制,我们一起来看看吧!

1.1 CAS 具体步骤

CAS 机制的基本思想是,先比较内存 V 中的值与寄存器 A 中的值(旧的预期值),是否相等,如果相等,则将寄存器 B 中的值(需要修改的新值)写入内存中,如果不相等,则不作任何操作,这整个过程是原子的~

CAS 涉及到以下三个操作,假设内存中的原数据V,旧的预期值A,需要修改的新值B

  • 读取内存值:将需要修改的值从主内存中读入本地线程缓存或工作内存
  • 比较并尝试交换:比较 A 与 V 是否相等,如果比较相等,将 B 写入 V,如果不相等,不作任何操作
  • 返回操作结果:如果成功更新了值,则返回成功标志或新值,如果失败更新,则返回失败标志或当前内存中的值

1.2 CAS 伪代码

如果把 CAS 想象成一个函数,可以得到 CAS 的伪代码,但是下述的伪代码,并不是真正的 CAS 代码,事实上,CAS 操作是一条由 CPU 硬件支持、原子的硬件指令,而这一条指令就可以完成下述这一段代码的功能(CAS 本身就是对应一条 CPU 指令,不可拆分的最小单位,此时,CAS 中比较和交换动作是没办法再拆分的)

boolean CAS(address,expectValue,swapValue) {
	if(&address == expectedValue) {
		&address = swapValue;
		return true;
	}
	return false;
}

图解如下:
在这里插入图片描述
可以知道,上述这一段代码,非原子,运行过程中可能随着线程的调度有概率产生线程安全问题,而原子指令不会有线程安全问题~

同时,CAS也不会有内存可见性的问题,内存可见性是编译器把一系列指令进行调整,把读内存指令调整成直接读寄存器的指令,效率大大提升,可能会误判,从而产生 bug,但是 CAS 本身就是指令级别读取内存的操作,因此,不会有内存可见性带来的线程安全问题

CAS 可以不加锁也能一定程度保证线程安全!这样就可以基于 CAS 机制,实现一系列操作

上一篇:并查集的模拟实现


下一篇:②EtherCAT转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关-写单个寄存器