摘要:本篇主要介绍了【Java开发详解】Java内存模型中 happens-before规则,通过具体的内容展现,希望对Java开发的学习有一定的帮助。
本篇主要介绍了【Java开发详解】Java内存模型中 happens-before规则,通过具体的内容展现,希望对Java开发的学习有一定的帮助。
Java内存模型中 happens-before规则
如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作课件,并且第一个操作的执行顺序排在第二个操作之前。
两个操作间存在happens-before关系,不意味着Java平台一定按照被该关系制定的顺序执行,如果重排序后不按照该顺序,但结果一致,那么这种重排序合法。
程序顺序规则:
一个线程中,按照程序执行的顺序,前面的操作happens-before于后面的操作。
也就是符合单线程的思维,程序在前面对变量的修改对后续操作可见。
监视器锁规则(管程锁):
一个锁的解锁 Happens-Before 于后续对这个锁的加锁
管程:通用的同步原语,在Java语言中是synchronized的实现
synchronized中的加锁解锁操作是隐式的,前一个线程的解锁对后一个线程的加锁可见,这保证了对共享变量的可见性。
volatile变量规则:
对一个volatile域的写,Happens-Before于对该域的读。
传递性:A Happens-Before B,B Happens-Before C,则A Happens-Before C
结合例子来看:
class VolatileExample {
int x = 0;
volatile boolean v = false;
public void writer() {
x = 42;
v = true;
}
public void reader() {
if (v == true) {
}
}
}
根据规则1:x=42 Happens-Before于 v=true
根据规则3:volatile 修饰的变量v=true的写 Happens-Before 于v=true的读
根据规则4:x=42 Happens-Before 于v=true的读,也就是我们读到的x为42
避免了多线程中CPU 缓存而导致可见性问题。
start()规则:父线程A中执行了子线程B的ThreadB.start()操作,则该操作 Happens-Before 于线程B中任何操作
Thread B = new Thread(()->{
});
// 此处对共享变量 a 修改对B可见
a = 77;
// 主线程启动子线程
B.start();
join()规则:线程等待原则,如果在线程 A 中,调用线程 B 的 join() 并成功返回,那么线程 B 中的任意
操作 Happens-Before 于该 join() 操作的返回
Thread B = new Thread(()->{
a = 66;
});
B.start();
B.join()
// 子线程所有对共享变量的修改在主线程调用 B.join() 之后皆可见,A中看到a=66
线程中断规则:对线程interrupt()方法的调用 Happens-Before 于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。
对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始。
✅ 扫码免费获取IT基础课程 · IT技术干货 · 答疑解惑 · 职业测评
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号