跳转到正文
Siolin'Log
返回

Java 内存模型:happens-before 与可见性

概述

JMM(Java Memory Model,Java 内存模型)解决的核心问题是:多线程同时读写共享数据时,Java 如何规定可见性、执行顺序和同步语义。它让不同 CPU、操作系统和 JVM 对并发程序遵守同一组合法行为约束,但并不保证存在数据竞争的程序每次都得到相同结果。

JMM 不是一种具体的内存结构,也不是 JVM 运行时数据区,而是一套并发语义规范。

如果需要先理解原子性、可见性和有序性的区别,可以阅读 Java 并发问题:原子性、可见性与有序性

happens-before

规则

happens-before 是 JMM 描述跨线程可见性与顺序保证的核心关系。

如果操作 A happens-before 操作 B,那么 A 的结果必须对 B 可见,并且 A 的执行顺序先于 B。它描述的是内存模型保证的偏序关系,不等同于简单的墙上时钟先后,也不意味着 JVM 不能进行保持该关系的优化或重排序。

常用规则:

示例

class Data {
    int value = 0;
    volatile boolean ready = false;

    void write() {
        value = 42;
        ready = true;
    }

    int read() {
        if (ready) {
            return value;
        }
        return -1;
    }
}

如果线程 A 执行 write(),线程 B 之后读到 ready == true,那么线程 B 也必须看到 value == 42

链条是:

  1. 在线程 A 内,value = 42 happens-before ready = true
  2. ready = true 是 volatile 写,happens-before 线程 B 对 ready 的 volatile 读。
  3. 在线程 B 内,读 ready happens-before 读 value
  4. 根据传递性,value = 42 对线程 B 可见。


上一篇
Java Condition:条件等待、通知与队列转移
下一篇
Java ReentrantLock:重入、公平性与条件队列