在 Java 中,除了常见的底层锁和并发集合类,java.util.concurrent
包还提供了一组专门用于原子操作的封装类,位于 java.util.concurrent.atomic
包。通过这些类,我们可以在多线程环境下安全地进行无锁操作,避免了传统锁的性能开销。今天我们就来详细了解其中一个常用的类:AtomicInteger
。
1. 原子操作类概述
java.util.concurrent.atomic
包中的类提供了一些常见的数据类型(如 AtomicInteger
, AtomicLong
)的原子操作。这些类的核心特性是它们通过无锁(lock-free)方式实现线程安全,从而避免了传统同步机制的性能瓶颈。
我们以 AtomicInteger
为例,来了解其提供的一些常见操作:
1.1 主要操作
-
增加值并返回新值:
int addAndGet(int delta)
该方法将给定的增量delta
加到当前值,并返回更新后的新值。 -
加1后返回新值:
int incrementAndGet()
该方法将当前值加1,并返回加1后的新值。 -
获取当前值:
int get()
该方法返回当前的值。 -
使用CAS方式设置:
boolean compareAndSet(int expect, int update)
该方法通过比较当前值是否为expect
,如果相等,则将其更新为update
,并返回true
,否则返回false
。
1.2 CAS(Compare and Set)操作
AtomicInteger
以及其他原子类的底层实现基于 CAS(Compare and Set) 操作。CAS 操作是一种无锁的线程安全机制,其原理是:在操作过程中,它会比较当前值和预期值是否一致,如果一致,则更新为新值;如果不一致,说明另一个线程已修改了值,当前线程会重新获取最新的值。
举个例子,如果我们自己通过 CAS 编写 incrementAndGet()
方法,它大概长这样:
java
public int incrementAndGet(AtomicInteger var) {
int prev, next;
do {
prev = var.get(); // 获取当前值
next = prev + 1; // 增加1
} while (!var.compareAndSet(prev, next)); // CAS操作,直到成功
return next; // 返回更新后的值
}
CAS 操作保证了即使多个线程同时修改 AtomicInteger
的值,也能确保最终的更新是正确的。
2. 使用 AtomicLong 实现全局唯一ID生成器
AtomicLong
和 AtomicInteger
类似,用于提供对 long
类型数据的原子操作。我们可以使用它来实现一个线程安全的全局唯一 ID 生成器。例如:
java
class IdGenerator {
AtomicLong var = new AtomicLong(0);
public long getNextId() {
return var.incrementAndGet(); // 线程安全的自增操作
}
}
在这个例子中,AtomicLong
用于生成一个递增的全局唯一 ID。每次调用 getNextId()
时,var
会自增 1,并返回新值。
3. Java 8 中的新原子类:LongAdder 和 LongAccumulator
在高竞争场景下,AtomicInteger
和 AtomicLong
的性能可能会有所下降。为了解决这个问题,Java 8 引入了 LongAdder
和 LongAccumulator
,这两个类在高并发情况下能提供更好的性能。
-
LongAdder:专为高并发环境设计,通过将数据分配到多个变量上,减少了线程间的竞争。它适用于高并发的累加场景。
-
LongAccumulator:与
LongAdder
类似,但它允许用户自定义累加操作。
这两个类的设计使得在高度竞争的环境下,也能保证性能的优化。
4. 小结
-
原子操作:通过
java.util.concurrent.atomic
包提供的类(如AtomicInteger
和AtomicLong
),我们可以实现无锁的线程安全操作,避免了传统锁带来的性能开销。 -
适用场景:这些原子类适用于计数器、累加器等需要频繁更新的场景,尤其是在高并发环境下,它们的表现优于传统的同步机制。
-
使用方便:
AtomicInteger
提供了简单易用的操作方法,如incrementAndGet()
、compareAndSet()
等,使得多线程编程更加简洁高效。
通过使用原子类,开发者可以在保证线程安全的同时,提升程序的性能,避免了传统锁机制的瓶颈,特别是在高并发场景下,能够有效地提高系统的吞吐量。
标签:Java,16,int,AtomicInteger,CAS,线程,AtomicLong,操作,多线程 From: https://blog.csdn.net/max202011161630/article/details/144836378