Java AtomicLong
最后修改于 2025 年 5 月 25 日
在本文中,我们将使用 Java 的 AtomicLong
。
AtomicLong
提供了一个可以原子读取和写入的 long 变量。它确保对变量的操作是线程安全的,从而防止并发环境中出现诸如丢失更新之类的问题。
AtomicLong 是 java.util.concurrent.atomic
包中的一个类,它提供了一种原子且线程安全的方式来表示和操作 long 原始数据类型。
AtomicLong
是一种同步原语。它为 long 值提供原子操作,确保线程安全地访问和修改。与传统的锁(可能会引入性能开销)不同,AtomicLong
利用底层原子指令来维护数据一致性,而无需阻塞线程。它的主要目的是高效地处理并发更新,同时避免竞争条件。
主要特点
-
原子操作:
AtomicLong
保证对底层 long 值的读取和写入操作都是原子的。这意味着每个操作都作为一个单一的、不可分割的单元执行,即使多个线程试图同时访问该值。这可以防止在多线程环境中,常规 long 变量可能出现的不一致性和数据竞争。 -
线程安全: 通过确保原子操作,
AtomicLong
可以安全地跨多个线程使用相同的 long 值,而无需显式的同步机制(如锁)。这简化了线程安全编程,并降低了并发问题的风险。 - 常见操作: 该类提供了各种方法来原子地执行对 long 值的操作,例如检索当前值、设置新值、递增或递减该值,以及执行比较和交换操作。
使用 AtomicLong
的好处
- 防止数据竞争: 保证原子操作避免了当多个线程尝试同时读取或写入同一个 long 值时可能出现的不一致性。
- 简化并发编程: 消除了在多个线程访问 long 变量的情况下对复杂同步代码的需求。
- 提高性能: 原子操作可能比使用锁更有效,特别是对于频繁访问的变量。
AtomicLong
的用例
-
计数器:
AtomicLong
非常适合表示在并发环境中由多个线程递增或递减的计数器,例如跟踪网站访问者或活动的网络连接。 - 序列号: 它可用于生成唯一且原子递增的序列号,这对于日志记录或事务 ID 等目的非常有用。
-
状态标志:
AtomicLong
可以用作一个简单的标志变量,多个线程可以原子地设置或重置该变量,以指示特定的状态或条件。
计数器示例
在下一个示例中,我们生成 500 个线程。每个线程都会递增一个计数器。
Main.java
class Counter { private final AtomicLong counter = new AtomicLong(0); public void inc() { counter.getAndIncrement(); } public long get() { return counter.get(); } } void main() throws InterruptedException { final Counter counter = new Counter(); // 500 threads for (int i = 0; i < 500; i++){ var thread = new Thread(counter::inc); thread.start(); } // sleep three seconds Thread.sleep(3000); System.out.println("Value: " + counter.get()); }
最后,计数器应该是 500。
private final AtomicLong counter = new AtomicLong(0);
计数器是一个初始化为 0 的 AtomicLong
。
public void inc() { counter.getAndIncrement(); }
inc
方法安全地递增计数器。
public long get() { return counter.get(); }
get
方法返回计数器的当前值。
来源
在本文中,我们使用了 Java 中的 AtomicLong
。
作者
列出所有Java教程。