指令重排问题

本文探讨了在Java中,由于指令重排可能导致的半初始化问题,以及如何通过volatile关键字和DCL(Double-Check Locking)双重锁机制来解决这类问题。volatile能防止指令重排,确保多线程环境下的可见性和有序性,但可能影响CPU利用率。DCL机制则在提高效率的同时,确保单例模式的正确初始化,避免了线程安全问题。
摘要由CSDN通过智能技术生成
指令重排问题:
前提条件:

半初始化-阶段:

1.分配内存空间
2.初始化
3.建立关联

问题:
  1. 前后指令没有任何内存屏障的情况下,底层为了提高利用率在上下级没有依赖关系的指令,且最终执行结果一致的情况下将会产生指令重排提升效率没必要在某一个耗时的指令上卡住。
  2. 如:初始化(半初始化-阶段2-初始化)耗时较长的情况下,会默认先给分配的内存空间与地址值建立关系也就是(半初始化-阶段-3 建立关联)
解决方案:
  1. volatile: 建立上下指令之间的内存屏障;

好处: 解决指令之间的顺序问题,禁止重排序;
缺点: cpu利用率降低,因为顺序执行的原因,如果是一个thread存在多条指令,将会在一些较为耗时的指令上花费较长时间,才能获取最终执行结果;

  1. 使用 DCL(double check lock) 双重锁机制;

第一步提高效率先判断对象是否为空(不直接使用synchronized),如果已经存在,就直接返回对象即可;
第二步使用synchronized锁,保证多请求情况下指令的执行顺序;
第三步再次判断是否为空,如果为空:创建对象,绑定关系,返回对象;

public class Thread007DCL {

    private static volatile Thread007DCL thread007DCL;

    public Thread007DCL() {
    }

    public static Thread007DCL getInstance(){
        if (thread007DCL == null) {
            // double check lock
            synchronized (Thread007DCL.class) {
                if (thread007DCL == null) {
                    thread007DCL = new Thread007DCL();
                }
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return thread007DCL;
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值