上一题下一题

在 Java 内存模型中,volatile 写与读如何建立 happens-before;它为何不能保证 i++ 这类复合操作的原子性?

基础版
来源:alibaba中级工程师并发原子性保障volatile内存语义volatile原子性限制Java内存模型happens-before
答案解析

在 JMM 中,对同一个 volatile 变量的写操作 happens before 之后对该变量的读操作。也就是说,线程 A 先执行 volatile 写,线程 B 随后读取这个变量时,A 在写入之前对其他共享变量的修改,对 B 也具有可见性;同时,volatile 还能禁止相关读写被随意重排序。

但 volatile 只保证可见性和有序性,不保证复合操作的原子性。i++ 实际上包含三个步骤:

即使 i 是 volatile,多个线程仍可能同时读取到相同的旧值。例如两个线程都读取到 0,各自计算出 1,然后分别写回 1,最终结果就是 1 而不是 2,这就是丢失更新。

如果需要保证自增的原子性,可以使用 AtomicInteger.incrementAndGet()、synchronized 或 Lock;高并发计数场景下也可以考虑 LongAdder。

登录后查看完整内容