在中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在关系。
JMM可以通过happens-before关系向程序员提供跨线程的内存可见性保证(如果A线程的写操作a与B线程的读操作b之间存在happensbefore关系,尽管a操作和b操作在不同的线程中执行,但JMM向程序员保证a操作将对b操作可见)。
happens-before原则:
happens-before规则:
- 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作;
- 锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作;
- volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读
- 传递规则:如果A happens-before B,且B happens-before C,那么A happens-before C
- 线程启动规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作- happens-before于线程B中的任意操作
- 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生;
- 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;
- 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始;
通俗解释:
第一次接触该概念是在 方腾飞写的<<JAVA并发编程的艺术>>这本书, 初次接触感觉整章概念比较多, 有些晦涩, 在反复阅读和求助大神后有了一些理解, 记录在这
这条happens-before规则让人费解的地方就是happens-before规则的描述到底和谁在前边谁先执行有什么区别
<<JAVA并发编程的艺术>>有一句注意:
这句话就是对这个问题的解释, 但也是让我最费解的一句话, 我们拆开理解:
总结一下这句话: happens-before不要求前一个操作和后一个操作的发生顺序, 仅仅要求前一个操作的执行完成并刷新回内存发生在后一个操作结果之前
为啥要区别操作的开始和结束呢?
大家应该也能猜到, 先开始的操作不一定先结束,JMM可以通过重排序等手段让代码顺序里靠后的指令先执行, 至于为什么要这样要去理解重排序的意义: 为啥要指令重排序
为啥要强调完成并刷新回内存(对后操作可见)呢?
这个是因为JAVA内存模型有本地缓存的抽象概念, 指令执行完结果放在本地缓存其他线程是看不到的, 要刷新回主内存对其他线程才可见(大家看到内存的结果才知道这个指令执行完了) , 这要大家去看JAVA内存模型(JMM)
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/12692.html