Appearance
并发内存模型:用 happens-before 理解可见性
修订于 2026-10-12。本文不包含虚构的线上事故和未经测试的性能数字。
一个线程按源代码顺序执行,并不意味着另一个线程会以同样顺序观察它的写入。编译器、处理器和运行时都可能在各自的语言规则内优化执行。并发程序需要语言定义的同步关系,而不是靠“本机测试没问题”推断安全。
happens-before 是什么
它描述一个操作的结果何时必须对另一个操作可见。以 Go 内存模型为例,同一 goroutine 内的程序顺序、通道通信、互斥锁和原子操作等可建立同步关系。没有适当同步的共享读写可能构成数据竞争。
Java 内存模型也通过 happens-before 等规则规定跨线程可见性,但具体同步动作与 Go 不完全相同。不能把某种语言的 volatile、atomic 或锁语义直接照搬到另一种语言。
实际写法
- 优先用清楚的锁、通道或并发容器保护共享数据。
- 原子变量适合简单状态;多个变量必须一起变化时,考虑锁或事务。
- 发布对象后,不要在没有同步的情况下继续修改其共享字段。
- 用竞态检测、压力测试和代码审查协同检查;单次测试无法穷尽调度情况。
内存模型帮助解释代码“允许发生什么”,并不承诺给程序自动排序。先写出正确的同步关系,再评估是否需要针对性能做更底层的优化。