使用 atomicinteger 可安全共享并递增计数——需所有 runnable 共享同一实例,通过构造参数传入;调用 incrementandget() 或 getandincrement() 实现原子递增,避免非原子操作。

在多个 Runnable 实例间共享并安全地递增计数,用 AtomicInteger 是最简洁可靠的方式——关键在于让所有实例共享同一个 AtomicInteger 对象,而不是各自创建。
确保所有 Runnable 共享同一个 AtomicInteger 实例
每个 Runnable 如果都 new 一个自己的 AtomicInteger,那就不是“共享计数”,而是各自计数。必须通过构造参数、静态字段或外部传入等方式,让它们引用同一个实例。
- 推荐做法:在创建
Runnable时,把同一个AtomicInteger作为构造参数传入 - 不推荐:在
Runnable内部声明static AtomicInteger counter = new AtomicInteger()(虽能共享,但耦合强、难测试、易被其他类误改) - 更灵活的做法:将
AtomicInteger封装进任务上下文或服务类中统一管理
在 run() 中调用 incrementAndGet() 或 getAndIncrement()
AtomicInteger 的递增操作本身就是原子的,无需额外同步。常用方法:
-
incrementAndGet():先加 1,再返回新值(适合需要立刻拿到最新计数值的场景) -
getAndIncrement():先返回当前值,再加 1(适合“取号”类逻辑,比如分配唯一序号) - 避免直接用
++或counter.get() + 1,这不是原子操作,会丢失更新
示例代码:线程安全的全局任务编号分配
下面是一个典型用法:启动 10 个线程执行任务,每个任务获取一个唯一递增编号:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
AtomicInteger globalId = new AtomicInteger(0); for (int i = 0; i <p>输出类似:<code>Task 1 running in Thread-0</code>、<code>Task 2 running in Thread-1</code>……不会出现重复 ID 或跳号。</p> <h3>注意可见性与初始化边界</h3> <p><code>AtomicInteger</code> 本身保证了原子性和内存可见性,但仍需注意初始化时机:</p>
-
AtomicInteger实例必须在所有线程启动前完成初始化(如上面例子中先 new 出来,再传给各 Runnable) - 不要在多线程环境下懒汉式初始化(如双重检查锁里 new AtomicInteger),除非你明确控制了发布安全
- 如果计数需从特定值开始,用
new AtomicInteger(initValue),比如new AtomicInteger(1001)
不复杂但容易忽略:共享对象、原子方法、初始化顺序,这三点到位,就能稳稳实现跨 Runnable 的线程安全计数。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










