“无锁”指不使用java monitor锁而依赖cpu的cas指令实现原子更新,通过读取-计算-cas重试机制完成线程安全自增,避免线程阻塞。

Java 中用 AtomicInteger 实现无锁原子自增,核心是调用其线程安全的 incrementAndGet() 或 getAndIncrement() 方法,底层依赖 CPU 的 CAS(Compare-And-Swap)指令,无需 synchronized 锁。
为什么叫“无锁”?
“无锁”不是完全没有锁机制,而是不使用 Java 的 monitor 锁(即不阻塞线程),而是通过硬件级 CAS 指令完成原子更新:先读取当前值,计算新值,再尝试用 CAS 原子地把旧值替换成新值;若期间其他线程修改了该值,CAS 失败,就重试直到成功。整个过程不挂起线程,也不需要加锁释放锁。
基本用法:两种常用自增方式
AtomicInteger 提供了两个语义略有不同的自增方法:
-
incrementAndGet():先自增,再返回新值(类似
++i) -
getAndIncrement():先返回当前值,再自增(类似
i++)
示例:
int count = new AtomicInteger(0).incrementAndGet(); // 返回 1典型场景:多线程计数器
替代 volatile + synchronized 的低效组合。例如统计请求次数:
- 声明一个
static final AtomicInteger counter = new AtomicInteger(0); - 每个线程执行
counter.incrementAndGet();即可安全自增 - 无需额外同步块,也不会出现丢失更新(如两个线程同时读到 100,都写回 101)
注意点和常见误区
虽然操作原子,但复合逻辑仍需谨慎:
- 单独的
incrementAndGet()是原子的;但if (ai.get() 不是原子的——判断和自增之间存在竞态窗口 - 如需条件更新,应使用
compareAndSet(expected, updated)手动实现 CAS 循环 - 不要把它当普通 int 用:不能直接参与算术表达式(如
ai + 1),必须调用get()显式取值
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











