内存模型
# 内存模型
# 内存模型
# JMM 与硬件内存连接
# 对象共享后的可见性
如果两个或多个线程共享一个对象,而没有正确使用 volatile 声明或同步,则一个线程对共享对象的更新可能对其他线程不可见。
# 竞态条件
如果两个或多个线程共享一个对象,并且多个线程更新该共享对象中的变量,则可能会出现竞态。
想象一下,如果线程 A 将共享对象的变量计数读入其 CPU 缓存中。 想象一下,线程 B 也做同样的事情,但是进入不同的 CPU 缓存。 现在,线程 A 将一个添加到 count,而线程 B 执行相同的操作。 现在 var1 已经增加了两次,每个 CPU 缓存一次。
如果这些增量是按先后顺序执行的,则变量计数将增加两次并将原始值 + 2 写回主存储器。
# 内存可见性保证
Java 程序的内存可见性保证按程序类型可以分为下列三类:
- 单线程程序。单线程程序不会出现内存可见性问题。编译器,runtime 和处理器会共同确保单线程程序的执行结果与该程序在顺序一致性模型中的执行结果相同。
- 正确同步的多线程程序。正确同步的多线程程序的执行将具有顺序一致性(程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同)。这是 JMM 关注的重点,JMM 通过限制编译器和处理器的重排序来为程序员提供内存可见性保证。
- 未同步 / 未正确同步的多线程程序。JMM 为它们提供了最小安全性保障:线程执行时读取到的值,要么是之前某个线程写入的值,要么是默认值(0,null,false)。