一、概述
1.Java内存模型(Java Memory Model或JMM)里定义的happens-before 规则指的是:用于描述多线程中变量读写等不同操作之间的内存可见性,若操作 A happens-before 操作 B ,那么操作 A 的结果对操作 B 可见。
2.happens-before 规则分为单线程和多线程的情况:
1)单线程下的 happens-before :
因为单线程内只有一份工作内存,不存在数据一致性的问题,所以字节码的先后执行顺序天然符合happens-before关系。
在程序中靠前的字节码 happens-before 靠后的字节码,即靠前
的字节码执行完之后的操作结果对靠后的字节码可见。但是,这并不意味着前者一定在后者之前执行。若后者不依赖前者的运行结果,那么它们可能会被重排序。
2)多线程下的 happens-before:
多线程中由于每个线程都有共享变量的工作内存副本,如果没有对共享变量做同步处理,线程1更新A共享变量的值之后,线程 2 开始执行操作 B,此时操作 B 不一定能看见变量 A 被更新后的值。
二、详细
Java 内存模型实现了下述支持 happens-before 关系的操作:
1. 程序顺序规则: 一个线程内,按照代码顺序,书写在前面的操作 happens-before 书写在后面的操作。
2. 锁规则: 对一个锁的 unlock 操作 happens-before 后面对同一个锁的 lock 操作。
3. volatile 变量规则: 对一个volatile变量的写操作 happens-before 后面对这个变量的读操作。volatile关键字保证变量在不同线程之间的可见性。
4. 传递规则: 若操作 A happens-before 操作 B,而操作 B 又 happens-before 操作 C,则操作 A happens-before 操作 C。
5. 线程启动规则:Thread 对象的 start()方法 happens-before 此线程内的任何代码的执行。
6. 线程中断规则: 对线程 interrupt()方法的调用 happens-before 被中断线程的代码检测到中断事件的发生(通过静态方法Thread.interrupted()或实例方法Thread.isInterrupted()调用)。
7. 线程终结规则: 线程中所有的操作都 happens-before 线程的终止检测,我们可以通过 Thread.join()方法等待线程结束、Thread.isAlive()的返回值为false等手段检测到线程是否已经终止执行。
8. 对象终结规则: 一个对象的构造方法执行完毕 happens-before 它的 finalize()方法的开始执行。
微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。
我是程序员小迷(致力于C、C++、Java、Kotlin、Android、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。
欢迎关注。助您在编程路上越走越好!