阿里面试题:Java 并发编程之 happens-before 规则

本文探讨了Java内存模型(JMM)中的happens-before原则,用于解决并发编程中的脏读问题。通过同步机制如`synchronized`和`volatile`关键字确保线程间的操作顺序,防止指令重排序导致的错误。文章通过双重检查锁定的单例模式示例,解释了`volatile`关键字如何应用在happens-before规则中,以保证并发安全。
摘要由CSDN通过智能技术生成

JMM



JMM 即 Java 内存模型,它是对共享内存的并发模型。我们知道,Java 中的共享变量是存储在主内存中的,而线程有自己的工作内存,如果一个线程要操作一个共享变量,它会将共享变量赋值一份到自己的工作内存,进行操作后,再将最新的变量值回写到主内存中。

在这里插入图片描述

假设有线程 a 对共享变量 x 读取进行更新后及时回写到主内存,然后线程 b 再读取共享变量 x 的值进行操作,这是正常没问题的。但是如果线程 a 对共享变量 x 更新后没有及时回写到主内存,这时线程 b 读取到共享变量 x 的值进行操作,这就出现脏读的现象。

要处理以上并发脏读的问题也简单,可以使用同步机制控制多线程之间操作的顺序,例如使用 synchronzied 关键字;或者使用 volatitle 关键字强制将线程更新后的最新值回写到主内存,以便其他线程可见。这都是 JMM 中 HB 的体现。

指令重排序



我们知道,JVM 会对我们写的代码进行优化,其中一个优化点就是编译器和处理器对指令进行重排序。虽然这些优化能提高程序性能,但是有可能会出现优化后执行的结果不是我们预想的结果,所以需要 happens-before 规则来禁止一些编译优化的场景,保证并发编程的正确性。

JMM 并不是全部禁止指令重排序,对于不会改变程序执行结果的重排序,JMM 允许编译器和处理器这样做。而对于会改变程序执行结果的重排序,JMM 会禁止这种重排序。

以我们最熟悉的 double-check 懒汉式单例模式为例,网上会告知如下程序是没问题的。

package com.chenpi;

/**

  • @Description

  • @Author Mr.nobody

  • @Date 2021/6/22

  • @Version 1.0

*/

public class Singleton {

private

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值