简介
由于 Java 内存模型是个复杂的规范,可从不同视角解读。从程序员的视角可以理解为:它为我们提供了如何禁用缓存和编译优化的方法。具体来说,这些方法包括 volatile、synchronized 和 final 三个关键字,以及八项 Happens-Before 规则。
Happens-Before 规则
- 顺序性规则:在一个线程中,按照程序顺序,前面的操作 Happens-Before 于后续的任意操作。
- volatile 变量规则:一个 volatile 变量的写操作, Happens-Before 于后续对这个 volatile 变量的读操作。
- 传递性:如果 A Happens-Before B,且 B Happens-Before C,那么 A Happens-Before C。
- 管程中锁的规则:一个锁的解锁 Happens-Before 于后续对这个锁的加锁。
- 线程 start() 规则:主线程 A 启动子线程 B 后,子线程 B 能够看到主线程在启动子线程 B 前的操作。
- 线程 join() 规则:主线程 A 等待子线程 B 完成(主线程 A 通过调用子线程 B 的 join() 方法实现),当子线程 B 完成后(主线程 A 中 join() 方法返回),主线程能够看到子线程的操作。当然所谓的“看到”,指的是对共享变量的操作。
- 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。
- 对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。
关键字
- volatile:最原始的意义就是禁用 CPU 缓存
- synchronized: Java 里对管程的实现,管程是一种通用的同步原语。
- final:修饰变量时,初衷是告诉编译器:这个变量生而不变,可以可劲儿优化。
网友评论