盘点Java中基于CAS实现的原子类

网站建设3年前发布
18 0 0

JDK中提供了一系列的基于CAS实现的原子类,CAS 的全称是Compare-And-Swap​,底层是lock cmpxchg指令,可以在单核和多核 CPU 下都能够保证比较交换的原子性。所以说,这些原子类都是线程安全的,而且是无锁并发,线程不会频繁上下文切换,所以在某些场景下性能是优于加锁。,本文就盘点一下JDK中的原子类,方便我们后续拿来使用。,202303061228396477960021a0fb5c450793447806880f354c09893,这边以AtomicInteger讲解下它的API和用法。,使用:,202303061229408517b1221ed3a8014e34056fca80a43db8ffa0180,原理分析:,整体实现思路: 自旋(循环) + CAS算法,valueOffset:偏移量表示该变量值相对于当前对象地址的偏移,Unsafe 就是根据内存偏移地址获取数据,202303061230402233c0e69b6f5f70ccb69893cfbaaa2f515229209,从主内存中拷贝到工作内存中的值(每次都要从主内存拿到最新的值到本地内存),然后执行compareAndSwapInt()再和主内存的值进行比较,假设方法返回 false,那么就一直执行 while 方法,直到期望的值和真实值一样,修改数据。,20230306141248b86802854cbb25caaa96284b121ac8f06a0570533,原子类AtomicInteger的value​属性是volatile类型,保证了多线程之间的内存可见性,避免线程从工作缓存中获取失效的变量。,原子引用主要是对对象的原子操作,原子引用类分为AtomicReference、AtomicStampedReference、AtomicMarkableReference。它们之间有什么区别呢?,普通的原子类对象,调用compareAndSet()方法进行比较替换对象,但是如果使用AtomicReference类,会有一个ABA问题。什么意思呢?就是一个线程将共享变量从A改成B, 后面又改回A, 这是,另外一个线程就无法感知这个变化过程,就傻傻的比较,就以为没有变化,还是一开始的A,就替换了。 实际的确存在这样只要共享变量发生过变化,就要CAS失败,有什么办法呢?,带版本号的原子类对象,20230306123239c58ef7162e866050337547b66b573337972cd4304,其实有时候并不关心共享变量修改了几次,而是只要标记下是否发生过更改,是否加个标记即可,所以就有了AtomicMarkableReference类。,2023030612334066dd6e13310c09ee139606298124d084862cd1673,通过调用isMarked()方法查看是否发生变化。,直接上例子,202303061234396670b085670b81453a832676ad0d64bf8f5ae7842,利用字段更新器,可以针对对象的某个域(Field​)进行原子操作,只能配合 volatile 修饰的字段使用,否则会出现异常。,2023030612353967136d08823a19459977688a9cc266861ec27d387,原子累加器主要是用来做累加的,相关的类有LongAdder、DoubleAdder、LongAccumulator、DoubleAccumulator。,LongAdder​是jdk1.8中引入的,它的性能要比AtomicLong方式好。,LongAddr​ 类是 LongAccumulator​ 类的一个特例,只是 LongAccumulator​ 提供了更强大的功能,可以自定义累加规则,当accumulatorFunction​ 为 null 时就等价于 LongAddr。,这边做个性能的对比例子。,20230306123640634081f40dd661a19be327f8c5d2a38a7c2d37517,主要是由于LongAdder会设置多个累加单元,Therad-0 累加 Cell[0],而 Thread-1 累加Cell[1]... 最后将结果汇总。这样它们在累加时操作的不同的 Cell 变量,因此减少了 CAS 重试失败,从而提高性能。,本文总结了JDK中提供的各种原子类,包括基础原子类、原子引用类、原子数组类、原子字段更新器和原子累加器等。有时候,使用这些原子类的性能是比加锁要高的,特别是在读多写少的场景下。但是,不知道大家发现没有,所有的原子类操作对于一个共享变量执行操作是原子的,如果对于多个共享变量操作时,循环 CAS 就无法保证操作的原子性,还是老老实实加锁吧。

© 版权声明

相关文章