饿汉式 双重检测why

本文探讨了Java中单例模式在多线程环境下的实现,重点分析了懒汉式单例模式的两种优化方式:双重检查锁定(Double-Check Locking)和静态内部类。通过双重检查锁定,可以减少线程同步的开销,保证线程安全的同时提升效率。静态内部类则利用类加载机制确保单例的唯一性,避免同步带来的性能影响。
摘要由CSDN通过智能技术生成

问题1:单例模式在多线程环境下的lazy模式为什么要加两个if(instance == null)?

回答1:第一层 if (instance == null)是为了减少线程对同步锁锁的竞争,第二层if(instance==nul)是保证单例。即

(1)if (instance == null) 的懒汉式多线程下是不安全的;

(2)synchronized/lock + if (instance == null) 的懒汉式多线程下是安全的;

(3)if (instance == null) + synchronized + if (instance == null) 的懒汉式在(2)的情况下减少对同步锁的竞争,提高效率。

问题2:如回答1,既然第二种方式已经看保证线程安全了,为什么需要从第二种方式变为第三种方式?或者为什么要使用双层同步锁?或者第三种方式 if (instance == null) + synchronized + if (instance == null) 的懒汉式是如何减少对同步锁的竞争?

回答2:如果使用第二种方式,即第三种方式没有第一层if (instance == null) ,每次调用newInstance()方法都会先synchronized/lock 然后判断 if (instance == null) ,对于一共 n 次调用newInstance静态方法,对于第二层的 if (instance == null),只有第一次创建在为true,后面都是为false,不需要再次新建了,因为是单例,所以对于后面的 n-1 次调用newInstance,都是先获取到同步锁,然后 if(instance==null)为false,这样白白的消耗性能,后面的 n-1 次,每个线程辛辛苦苦的获取到的同步锁,发现没卵用,还不如不要获取同步锁,尝试的解决方法有两个:

① synchronized/lock + if (instance == null) 变为 if (instance == null) + synchronized/lock,但是这样修改后,第一批进入的线程破坏单例模式。

② synchronized/lock + if (instance == null) 变为 if (instance == null) + synchronized/lock + if (instance == null),在保证线程安全的第二种方式前面加一层 if (instance == null)判断,变为双层检测,这样在保证单例的情况下,提高效率,减少性能浪费。

问题3:为什么说刚才的第一种方式 synchronized/lock + if (instance == null) 变为 if (instance == null) + synchronized/lock ,无法保证第一批进入的线程仅创建一个对象?

回答3:虽然 if (instance == null) 实现后面调用阻止进入,提高了效率,同时 synchronized/lock 保证内部新建单例的原子性,但是由于没有内层 if (instance == null) ,第一批进入的每一个线程都会创建一个对象,破坏单例模式 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值