单例使用的场景:
1. 创建这样的对象需要消耗很多资源,比如说这个对象是包含线程池、缓存系统、网络请求等
2. 需要一个跟随系统创建和销毁的、提供全局访问数据的对象
几个特点:
1. 构造函数不对外开放
2. 通过静态方法或者枚举返回单例对象
3. 确保单例对象有且只有一个,尤其是在多线程环境下
4. 在需要被序列化传递时,要确保反序列化不会重新构造对象
懒汉模式:
1. 对于静态方法使用synchronized关键字保证同步,但是会有开销,而且每次调用静态方法都会进行同步操作
2. 单例的对象只有在第一次被使用时才会实例化,这是它的优点,也是名字的由来
DCL(Double CheckLock)模式:
1. 对于单例对象使用synchronized修饰
2. 进行2次单例对象是否为空的判断,第一次避免不必要的同步操作,第二次用于正常地创建实例
3. 能在需要时才创建实例,并能在大多数时候保证唯一性
4. 算是懒汉模式的优化版
静态内部类模式:
1. 使用静态static来修饰对象,同时使用new创建对象,可以保证唯一性
2. 单例被加载时都不会初始化对象,只有getInstance被调用才会初始化对象
3. 在单例内使用一个私有的静态内部类来保存单例对象
枚举模式:
1. 枚举实例默认是线程安全的
2. 不用考虑反序列化问题
3. 写法最简单
反序列化的方法:
在单例中实现抛出ObjectStreamException的readResolve的方法,在里面返回单例对象,这个方法是类共有的,在反序列化时会默认创建新的对象
单例的缺点:
扩展很困难,基本只能通过修改代码进行扩展;容易引发内存泄漏