单例模式的各种玩法

1、在private构造函数前,自己先创建一个唯一单例,然后在内部创建一个能获得单例的方法,让外部只能调用到这个唯一单例。
在这里插入图片描述缺点是:不管后面是否使用它,都会被加载。
2、那如果我们使用静态代码块呢?在我们的静态代码块中创建唯一实例
在这里插入图片描述发现跟玩法一差不多。
3、那我们还是希望这个实例,只有当我们要使用它的时候再加载它,这样就引出了懒加载的方式
在这里插入图片描述
但是这样,在多线程情况下,会造成线程安全问题。
4、那我们为了解决这个线程安全问题,在创建实例的方法加上一个线程同步的关键字synchronized关键字,是不是就行了呢?
在这里插入图片描述
这样确实是成功了,咱们的线程安全是得到了保障,可每一次调用这个方法,我们就要进行一次加锁的判断,势必又会导致效率的降低。那我们还有没有更好的办法呢?
5、如果我不把锁加在方法上,而是加在内部,减少同步代码块,是不是效率就能得打提高呢?
在这里插入图片描述
效率得到提高,但是线程安全又得不到保证了。那这个线程安全问题又是什么导致的呢?还是我们if语句和锁未能一体化操作的原因。
6、那既然这样,我在锁后面在进行一次实例对象是否为空的检查,是不是就能解决线程安全了?
在这里插入图片描述
这里不难发现,线程安全了,效率也得到了提升。那我的第一次if判断还需要吗?是不是去掉后,会更好呢?其实不是,正因为有了第一次的if判断,才为我们减少很多次不必要的上锁操作。
7、那我还想要优化,怎么办?我们可以引入匿名内部类,确保它在不被调用时,就不会被加载,这样既能利用到jvm的加载机制,保证单例,又能确保线程安全,还起到懒加载的作用。
在这里插入图片描述
但这样,就结束了吗?不,Java的创始作者之一,提供一种更为优化的方式。
8、那就是使用枚举,因为枚举类型也没有构造函数,它就是唯一的。
在这里插入图片描述
这样不仅能保证线程安全,效率提升外,还可以反序列化,可以说是这里面最优秀的方法了,但又由于它是枚举类型,在我们使用时,会很别扭。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值