双重校验单例为什么需要volatile

本文探讨了并发编程中的原子性、可见性和有序性等核心问题,并通过具体示例解释了这些问题如何影响程序的行为,尤其是在使用volatile关键字时的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 在并发编程中 我们经常会遇到三个问题,原子性,可见性 和有序性
    原子性是指多个操作,要么全部执行,要么全部不执行。有点类似于数据库中的事务。
    可见性是指其他线程可以看见某个线程对同一个变量操作后的值。
    有序性是指程序的运行具有有序性。例如代码的执行从上往下 创建对象一般分为三步
    1.分配内存空间。
    2.初始化对象
    3.将该内存空间的地址赋值给该对象
    static volatile EventBus defaultInstance;
    public static EventBus getDefault() {
    if (defaultInstance == null) {
    synchronized (EventBus.class) {
    if (defaultInstance == null) {
    defaultInstance = new EventBus();
    }
    }
    }
    return defaultInstance;
    }
    但是根据JMM的指令重排序实际过程可能会走1-3-2
    因为内存地址是存在的,
    所以不会走 if (defaultInstance == null) {
    defaultInstance = new EventBus();
    }所以会返回一个还未初始完成的对象
    当一个变量被volatile所修饰的时候也就保证了可见性,即当一个线程改变了这个变量的值,其他线程也能看到。也就是说Volatile保证了写在读取之前。还有就是它可以禁止指令重排序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值