happen-before是什么

happen-before是什么

happen-before出现的原因

为了明确定义多线程场景下重排序的问题,Java引入了JMM(Java Memory Model),也就是Java内存模型。如果有了重排序就会出现原子性,可见性,有序性的问题,但是性能会提升。所以Java内存模型不是真实存在的,而是一套规范,可以方便的使开发者在运行效率和程序开发的方便性之间找到一个平衡点。

一方面要让CPU和编译器可以灵活的进行重排序,另一方面也要告诉开发者,在什么情况下什么样的重排序不需要感知,需要感知什么样的重排序并作出处理。

为了描述这个规范,JMM引入了happen-before,使用happen-before描述两个操作之间的内存可见性

简单来说,happen-before的意思就是,如果 操作A happen-before 操作B,那么操作A的执行结果必须对操作B可见。

happen-before的七条原则

  1. 单线程规则:同一个线程中的每个操作都happens-before于出现在其后的任何一个操作。
  2. 对一个监视器的解锁操作happens-before于每一个后续对同一个监视器的加锁操作。
  3. 对volatile字段的写入操作happens-before于每一个后续的对同一个volatile字段的读操作。
  4. Thread.start()的调用操作会happens-before于启动线程里面的操作。
  5. 一个线程中的所有操作都happens-before于其他线程成功返回在该线程上的join()调用后的所有操作。
  6. 一个对象构造函数的结束操作happens-before与该对象的finalizer的开始操作。
  7. 传递性规则:如果A操作happens-before于B操作,而B操作happens-before与C操作,那么A动作happens-before于C操作。

happen-before的传递性

就像七条原则里的第七条,happen-before具有传递性,否则的话岂不是要将所有的可能出现可见性问题的变量都要用volatile修饰。

实例

class A{
	private int a = 0;
	private volatile int c = 0;

	public void set(){
		a = 5;	//操作1
		c = 1;	//操作2
	}
	public int get(){
		int d = c;	//操作3
		return a;	//操作4
	}
}

上述代码中,由于七条原则中的第一条:单线程规则,所以操作1 happen-before 操作2。由于变量c使用了volatile关键字进行修饰,所以操作2 happen-before 操作3。

所以由于传递性可以推出:操作1 happen-before 操作2 happen-before 操作3 happen-before 操作4

这样一来,操作1结果必须对操作4可见,但是如果没有使用volatile关键字修饰变量c,就不会有这样的关系,那么在先调用set方法后调用get方法时,就可能得不到值

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值