内存模型的基础
内存模型的抽象结构
共享变量 堆里面的对象、数组元素,静态变量(方法区)
局部变量 不会有线程可见性的问题,不会受内存模型的影响
指令重排
编译器优化的重排序 不改变单线程语义的前提下重新安排编译的顺序 --编译器
指令级并?的重排序 现在的处理器采用的技术,多条指令重叠进行,只要两条指令不存在数据依赖性 --处理器
内存系统的重排序 处理器会使用缓存或读写缓冲区的时候,程序运行的加载或存储这些操作看上去像是在乱序执行 -处理器
数据依赖性 --两个操作有同一个变量,且有一个操作是写操作
as-if-serial
定义:不管怎么重排序(编译器和处理器为了提?并?度),(单线程) 程序的执?结果不能被
改变。编译器、runtime和处理器都必须遵守as-if-serial语义。
happens-before
JMM设计意图
?
程序员对内存模型的使? 为程序员提供?够强的内存可?性保证
?
编译器和处理器对内存模型的实现 对编译器和处理器的限制要尽可能地放松
happens-before
在JMM中,如果?个操作执?的结果需要对另?个操作可?,那么这两个操作之间必须要存在happens-before关系。
?
程序顺序规则
?
监视器锁规则
?
volatile变量规则
?个线程中的每个操作,happens-before于该线程中的任意后续操作。
对?个锁的解锁,happens-before于随后对这个锁的加锁。
对?个volatile域的写,happens-before于任意后续对这个volatile域的读。
?
传递性 如果A happens-before B,且B happens-before C,那么A happens-before C。
?
start()规则
如果线程
A执?操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happens-before于线程B中
的任意操作。
如果线程
A执?操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()
操作成功返回。
对线程interrupt?法的调?happens-before于被中断线程的代码检测到中断事件的发?。
?
join()规则
?
线程中断规则
?
对象终结规则
?个对象的初始化的完成,也就是构造函数执?的结束?定 happens-before它的finalize()?法。
按时ifserial 创造了一个幻觉:程序员在写单线程程序的代码时是按程序的顺序进行的
happens before在我们创建正确同步的多线程的代码时也创造了一个幻觉:正确同步的多线程程序是按照happens before规则来执行的
一个happens-before规则,可能对应着多个处理器的编译器处理器的规则
每个处理器允许重排序的类型都不同
1.48.38