单例模式-设计模式

一、.单例模式运用场景

指在任何情况下都绝对只有一个单例,并提供一个全局访问点。如:公司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、不能被反射攻击

你可能感兴趣的:(单例模式-设计模式)