如何高效实现单例(Sinleton)设计模式


一、如何高效实现单例(Sinleton)设计模式

单例模式的基本概念

在这里插入图片描述
在这里插入图片描述

单例模式的不同实现方式及各自优势

饿汉式

在这里插入图片描述

懒汉式

在这里插入图片描述

懒汉式 + synchronized

在这里插入图片描述

懒汉式+Double Check

在这里插入图片描述
实际上不是线程安全的,instance() = new Singleton();可以分解成以下4个步骤
在这里插入图片描述

Volatile

在这里插入图片描述

对原始类型的读写都是原子类型的
long、double的读写不是原子类型的,加上volatile可以让它有原子性
volatile不保证对变量的加减操作是原子类型的,可以使用原子变量做到
当一个线程写了volatile变量之后可以立刻把这个变量刷新到主存去,让其他变量可以看到,不是放在缓存空间等一段才能看见。
禁止指令重排序

懒汉式+Double Check + Volatile

在这里插入图片描述
这里volatile的作用除了有序性,是不是可见性也需要volatile来保证呢?
没有,这里不需要volatile来保证可见性,有synchronized加上锁保证可见性。假如没有volatile,第二个线程拿到锁才能看到,第一个线程解锁,第二个线程加锁,如果第一个线程做了修改,第二个线程可以看见。即使没有volatile也可以保证可见性。

内部类Holder

在这里插入图片描述
实现了和double check 一样的功能,更加简洁。

单例模式实现的问题

在这里插入图片描述

枚举(Enum)

在这里插入图片描述
在这里插入图片描述
和饿汉式一样,加载时初始化,不是延迟初始化。可以抵抗反序列化工具和反射工具,对于枚举类型的反序列化,JVM有特别规定,要求反序列化只返回枚举类型的名字,到虚拟机里面再通过valueOf名字去构建一个新的实例,如果这个实例已经在了就把他构建,如果没在就构建一个新的实例,保证实例的唯一性。通过反射方法获取私有的构造函数,通过反射调用new instance时会报错,new instance会判断类型是不是枚举类型,如果是枚举类型就会报错。

单例模式实现总结

在这里插入图片描述

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值