JMM-多线程先行发生原则happens-before

本文详细探讨了JVM中的多线程先行发生原则——happens-before,包括其并发原则说明、总原则、8条具体规则和案例分析。并提出了针对并发问题的两种解决方案,分别是使用synchronized方法和应用volatile关键字。
摘要由CSDN通过智能技术生成

5.6 JMM规范下多线程先行发生原则之happens-before

在JVM中,如果一个操作执行的结果需要对另一个操作可见或者代码重排序,那么这两个操作之间

必须存在happens-before(先行发生)原则,逻辑上的先后关系。

5.6.2 先行并发原则说明 

5.6.3 happens-before总原则

5.6.4 happens-before之8条 

5.6.5 happens-before总结 

5.6.6 案例说明 

private int value =0;

public int getValue(){
    return value;
}

public int setValue(){
    return ++value;
}


问题描述:假设存在线程A和B,线程A先(时间上的先后)调用了setValue()方法,
然后线程B调用了同一个对象的getValue()方法,那么线程B收到的返回值是什么?

答案:不一定
分析happens-before规则(规则5,6,7,8可以忽略,和代码无关)
1 由于两个方法由不同线程调用,不满足一个线程的条件,不满足程序次序规则
2 两个方法都没有用锁,不满足锁定规则
3 变量没有使用volatile修饰,所以不满足volatile变量规则
4 传递规则肯定不满足
综上:无法通过happens-before原则推导出线程A happens-before 线程B,虽然可以确定时间上线程A优于线程B,但就是无法确定线程B获得的结果是什么,所以这段代码不是线程安全的

注意:
如果两个操作的执行次序无法从happens-before原则推导出来,那么就不能保证他们的有序性,
虚拟机可以随意对他们进行重排序

如何修复?

方法一:把getter/setter方法都定义为synchronized方法------->不好,重量锁,并发性下降

private int value =0;

public synchronized int getValue(){
    return value;
}

public synchronized int setValue(){
    return ++value;
}

方法二:把Value定义为volatile变量,由于setter方法对value的修改不依赖value的原值,满足

volatile关键字使用场景

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值