java.util.concurrent.AtomicInteger 源码阅读笔记
CAS 机制
自旋锁 + Unsafe类
比较当前工作内存中的值和主物理内存中的值,相同则执行规定操作,否则比较直到主内存和工作内存中的值一致为止。
CAS 底层原理
CAS的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。
UnSafe 类的 objectFieldOffset() 方法是一个本地方法,这个方法是用来拿到“原来的值”的内存地址,返回值是 valueOffset。
value 是由 volatile 修饰的,保证了value修改的可见性,在任何时刻任何线程总能拿到该变量的最新值。
CAS 的缺点
1. ABA 问题
例如:线程 1 从内存中取出 A,线程 2 也从内存中取出 A,线程 2 进行了一些操作将内存中的值变成了 B,然后又改回 A,这时候线程 1 进行 CAS 操作发现内存中仍然是 A,操作成功。虽然线程 1 的 CAS 操作成功,但是整个过程就是有问题的。
规避:在变量前面加版本号,AtomicStampedReference 类解决 ABA 问题,该类的 compareAndSet 方法作用是首先检查当前引用是否等于预期引用,并且当前 stamp 是否等于预期 stamp,如果全部相等,则以原子方式将该引用和该 stamp 的值设置为给定的更新值。
2. 循环尝试,多线程开销大
3. 只能保证一个共享变量的原子操作。
AtomicInteger 源码解读
AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方法来保证原子操作,从而避免 synchronized 的高开销,使执行效率大为提升。
1 | // setup to use Unsafe.compareAndSwapInt for updates |
AtomicInteger.getAndIncrement()
1 | /** |
- 本文作者: Kelly Liu
- 本文链接: http://tiantianliu2018.github.io/2020/03/20/Java-AtomicInteger-源码阅读笔记/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!