硬件同步原语(Atomic Hardware Primitives)是由计算机硬件提供的一组原子操作,我们比较常用的原语主要是 CAS 和 FAA 这两种。
基本概念
CAS(Compare and Swap)
先比较,再交换。伪代码:
<< atomic >>function cas(p : pointer to int, old : int, new : int) returns bool { if *p ≠ old { return false } *p ← new return true}
三个参数:
- p: 要修改变量的指针
- old: 原来的值
- new: 新的值
FAA(Fetch And Add)
先取值,然后进行增加,伪代码:
<< atomic >>function faa(p : pointer to int, inc : int) returns int { int value <- *location *p <- value + inc return value}
java实现和使用
java中 通过 Unsafe 类使用CAS和FAA
Unsafe unsafe=Unsafe.getUnsafe();
unsafe.getAndAddInt();// FAA
unsafe.compareAndSwapInt();// CAS
使用场景
- FAA和CAS的场景是: 获取值-->计算-->更改
- FAA和CAS相比与普通的锁,性能更好一些。 但是CAS由于需要用循环来处理compare失败的情况,所以如果遇到线程碰撞较多的场景,循环次数会明细那增加,cpu消耗会较大。 针对这种场景,可以采用 Yield() 缓解, 每次循环完成,调用Yield() 方法,让出当前线程占用的CPU资源给其他线程使用。
- 针对 “计算”是 简单的加减法,使用FAA会更适合。 CAS适用于更加复杂的 “计算”场景。