JVM 的指令重排问题

java语言规范规定JVM线程内部维持顺序化语义。即只要程序的最终结果与它顺序化情况的结果相等,那么指令的执行顺序可以与代码顺序不一致,此过程叫指令的重排序。

指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。
如何解决指令重排问题:
volatile: 建立上下指令之间的内存屏障
好处: 解决指令之间的顺序问题,禁止重排序;
缺点: cpu利用率降低,因为顺序执行的原因,如果是一个thread存在多条指令,将会在一些较为耗时的
指令上花费较长时间,才能获取最终执行结果;

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

代码如下,双重校验锁实现单例

//双重校验锁实现单例
public class synchronizedDemo {
//volatile 禁止jvm重排 保证内存的可见性
private volatile static synchronizedDemo uniqueIntance;

//private 构造函数私有化
private synchronizedDemo(){

}

private static synchronizedDemo  getUniqueIntance(){
    //锁外判断,避免每次进来都获取锁
    if(null == uniqueIntance) {
        synchronized (synchronizedDemo.class) {//锁内判断,避免多线程产生重复对象
            if (null == uniqueIntance) {
                uniqueIntance = new synchronizedDemo();

            }
        }
    }
        return uniqueIntance;
    }
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值