CAS(Compare And Swap比较并交换)
1.概念
cas非常重要!
CAS 操作包含三个操作数
- 内存位置(V)
- 预期原值(A)
- 新值(B)
CAS 用于同步的方式是从地址 V 读取值 A,执行多步计算来获得新 值 B,然后使用 CAS 将 V 的值从 A 改为 B。如果 V 处的值尚未同时更改,则 CAS 操作成功。
整个J.U.C都是建立在CAS之上的,因此对于synchronized阻塞算法,J.U.C在性能上有了很大的提升。
cas存在的问题:
-
ABA问题
- 一个线程将共享变量从A改成B再改成A,另一个线程执行cas时会认为共享变量没被修改过.
- 解决方案:AtomicStampedReference(使用jdk1.5之后的带有时间戳的原子类)
-
循环时间长,cpu开销大
- 原因:cas使用for(;; )实现,不会使线程进入休眠状态,cpu会一直空转.
-
只能保证一个共享变量的原子操作
- 对多个共享变量操作时,循环CAS就无法保证操作的原子性
- 解决方法:(1)使用锁 (2)AtomicReference
2.cas实现
do…while实现
/**
* 存在线程安全问题:
* (1)使用synchronized解决
* (2)使用ReentrantLock解决、
* (3)使用CAS+volatile解决(无锁)
*/
public void cost(int x) {
int t;
do {
t = balance.get(); //快照
} while (!balance.compareAndSet(t, t - x)); //CAS
}
while实现
其中的关键是 compareAndSet,它的简称就是 CAS (也有 Compare And Swap 的说法),它必须是原子操作。
是一种CPU指令级的原子性。
CAS 的底层是 lock cmpxchg 指令(X86 架构),在单核 CPU 和多核 CPU 下都能够保证【比较-交换】的原子性。
在多核状态下,某个核执行到带 lock 的指令时,CPU 会让总线锁住,当这个核把此指令执行完毕,再开启总线。这个过程中不会被线程的调度机制所打断,保证了多个线程对内存操作的准确性,是原子的。
CAS(Compare And Swap)是重要的同步机制,包括概念和实现两部分。CAS操作包含内存位置、预期原值和新值,若内存位置值未被其他线程改变则更新。但存在ABA问题和可能导致长时间循环导致CPU开销大。解决方案如AtomicStampedReference和使用锁。CAS通过compareAndSet方法实现,基于CPU的lock cmpxchg指令确保原子性。

204

被折叠的 条评论
为什么被折叠?



