- Java中有哪些原子类,原理是什么
AtomicInteger 和 AtomicLong:
用于对整数(int)和长整数(long)进行原子操作。
原理:它们内部封装了一个整型或长整型变量,并通过使用Unsafe类提供的CAS(Compare-and-Swap)操作来实现原子更新。CAS是一种无锁的同步机制,它在更新值时会检查预期值是否与当前值相等,如果相等则更新为新值,否则不进行任何改变。这种操作是原子的,即不会被其他线程中断,确保了多线程环境下更新的原子性和可见性。同时,这些类还使用了volatile关键字来确保变量的内存可见性,即当一个线程修改了该变量的值时,其他线程能够立即看到最新值。
AtomicBoolean:
用于对布尔值进行原子操作。
原理:类似于AtomicInteger和AtomicLong,AtomicBoolean内部封装了一个布尔值,并同样使用CAS操作来实现原子的set、getAndSet、compareAndSet等操作。volatile关键字同样用于确保布尔值的可见性。
AtomicReference:
用于对引用类型进行原子操作。
原理:它封装了一个对象引用,并通过CAS操作来原子地更新引用指向的对象。compareAndSet方法会比较当前引用与预期引用是否一致,一致则替换为新的引用,否则不作更改。同样,volatile关键字确保了对象引用的可见性。
AtomicIntegerArray 和 AtomicLongArray:
分别用于对整型数组和长整型数组进行原子操作。
原理:这两个类提供了对数组元素的原子更新操作,如getAndAdd、compareAndSet等。它们同样基于CAS机制,在更新数组元素时确保原子性,同时使用volatile数组元素来保证多线程环境下的可见性。
AtomicStampedReference:
带有标记(stamp)的引用类型原子操作类。
原理:除了维护一个引用外,还附加了一个整数标记。在进行原子更新时,不仅比较引用本身,还会比较标记值。这种设计可以解决ABA问题(即一个值被多次改变后又变回原始值,但期间发生了其他变化,仅通过比较值本身无法察觉)。compareAndSet方法会同时检查引用和标记是否符合预期,只有两者都满足条件才会更新。
AtomicIntegerFieldUpdater 和 AtomicLongFieldUpdater,以及 AtomicReferenceFieldUpdater:
这些类允许对指定类的某个非静态整型、长整型或引用类型字段进行原子更新。
原理:它们使用反射机制获取并操作指定对象的字段,同样基于CAS来实现原子更新。由于需要反射,使用时需提供目标类、字段名和访问权限修饰符。这些类适用于无法直接修改源代码以使用原子类的情况,但使用较为繁琐,且可能存在性能损失。
注:CAS是一种基于硬件级别的无锁同步算法,它通过原子性地比较和交换内存中的值来实现线程安全的更新操作。在Java中,CAS主要通过Unsafe类提供的方法实现,并被广泛应用在java.util.concurrent.atomic包下的原子类中。虽然CAS带来了高性能和无阻塞的优点,但也存在ABA问题、潜在的自旋开销以及对复杂同步场景支持不足等挑战。
如果大家需要视频版本的讲解,欢迎关注我的B站: