一、.单例模式运用场景
指在任何情况下都绝对只有一个单例,并提供一个全局访问点。如:公司CEO、部门经理,J2EE中 springContextConfig ApplicationContext 数据库的连接池等
二、单例模式的常见写法
饿汉单例模式

饿汉单例模式

饿汉单例模式 另一种写法
优点:加载的时候立即初始化.,没加任何的锁
缺点:某些情况下可能会内存浪费。大量饿汉单例,加载的时候即初始化
怎么解决?
懒汉式:被外部调用时候才创建

懒汉式单例
优点:需要的时候实例
缺点:线程不安全、加锁性性能低
这写法不够优雅,我们对他进行下优化,把锁放到创建对象上

双写检查锁 instance 检查两次。不能只检查一次
我们加上volatile 关键字,防止指令重排序
怎么解决?

用了Java本身语法特点 java内部类在调用的时候才加载
优点:写法优雅,利用了Java本身语法特点,性能高
缺点:可以被反射破坏
其实前面的写法都可以被反射破坏

拿到类的构造方法,暴力设置Accessible为true 创建实例对象
怎么解决?

解决被反射破坏,构造方法上加上判断
但是又带来一个缺点,写法不够优雅?有没有更好的方法?
注册式单例:每个实例都缓存都统一容器中,使用唯一的标识ID获取单例
1)枚举式单例

枚举对象

修饰符如果是枚举时不允许反射创建对象
有点:写法优雅,线程安全
缺点:枚举类似一个Map,map里面可以放很多对象,某些情况下可能造成内存浪费,不能大批量创建对象
Spring中怎么创建单例的呢?spring借鉴了枚举式写法,创建容器式IOC,实现单例

用的时候去IOC取,没有则创建一次
容器式有什么问题?
线程不安全
怎么解决?

对容器加锁
序列化破坏单例

加上readResolve解决序列化,有则不会重新创建对象
ThreadLocal 单例

ThreadLocal 单例,每个对象中只有一个,用过threadLocalMap实现
总结:
单例模式创建要点:
1、私有化构建器
2、全局访问点
3、线程安全
4、不能被序列化破坏
5、延时加载
6、不能被反射攻击