[Java-juc] Java 内存模型
2026年3月25日大约 2 分钟
[Java-juc] Java 内存模型
说一下你对 Java 内存模型的理解?
Java 内存模型就是定义主内存(共享内存)和工作内存(本地内存)进行交互的规则,
用来多线程环境下共享变量的内存可见性。
为什么线程要用自己的内存?
- 使用工作内存是为了提高性能,减少对主内存的频繁访问,
- 并且可以避免多个线程同时修改共享变量导致冲突。
i++是原子操作吗?
不是。
- 会先从内存中读取 i 的值。
- 然后对 i 的值进行加 1 操作。
- 最后将新的值写回内存。
说说你对原子性、可见性、有序性的理解?
总结
原子性保证操作不可中断,可见性保证变量修改后线程能看到最新值,有序性保证代码执行顺序一致,可以通过 volatile、synchronized 和 CAS 机制来保证这些特性。
- 原子性:操作不可分割,要么全部执行成功,要么完全不执行。(需要使用锁或原子类保证原子性)
- 可见性:一个线程对共享变量修改,能够及时被其他线程看见。(需要使用
volatile保证可见性) - 有序性:指程序是否按照代码的顺序执行。
说说什么是指令重排?
指令重排是CPU或编译器为了提高程序的执行效率,改变代码执行顺序的优化技术。
- 指令重排可能导致多线程环境下的可见性问题和有序性问题。
- 有三种重排序:
- 编译器重排序
- 并行指令重排序
- 内存系统重排序
happens-before 了解吗?
Happens-Before 是 Java内存模型定义的规则,用来保证两个操作之间的可见性。
happens-before 六大规则
- 程序顺序规则:单线程内部,代码按照顺序执行。
- 监视器锁规则:前一个线程释放锁操作发生在后一个线程获取锁之前。
- volatile 变量规则:对一个 volatile 修饰的字段写操作,发生在后续对这个字段的读操作之前。
- 传递性规则:如果A发生在B之前,B发生在C之前,那么A发生在C之前。
- 线程启动规则:如果线程A执行线程B的
start(),那么线程A的B.start()happens-before 线程B的任何操作。 - 线程终止规则:如果线程A执行线程B的
join(),那么join()之后的代码,必须等线程B执行完毕后才能执行。