懒汉模式
在第一次调用的时候实例化
双重检查锁模式
1 | /** |
注意点
- 这种写法在getSingleton方法中对singleton进行了两次判空,第一次是为了不必要的同步,第二次是在singleton等于null的情况下才创建实例。
- 使用volatile保证正确性,保证这个实体只在主存中存在。
静态内部类模式
1 | /** |
第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化sInstance ,这样不仅能确保线程安全也能保证Singleton类的唯一性,所以推荐使用静态内部类单例模式。
饿汉模式
饿汉式单例类:在类初始化时,已经自行实例化。
饿汉式
1 | /** |
实例直接使用final的模式,在构建后不可修改,又是static的,保证单例。
上述讲的几种单例模式实现中,有一种情况下他们会重新创建对象,那就是反序列化,将一个单例实例对象写到磁盘再读回来,从而获得了一个实例。反序列化操作提供了readResolve方法,这个方法可以让开发人员控制对象的反序列化。在上述的几个方法示例中如果要杜绝单例对象被反序列化是重新生成对象,就必须加入如下方法:
1 | private Object readResolve() throws ObjectStreamException{ |
枚举模式
1 | /** |
创建枚举默认就是线程安全的,所以不需要担心double checked locking,而且还能防止反序列化导致重新创建新的对象。保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量)。
枚举单例的优点就是简单,但是大部分应用开发很少用枚举,可读性并不是很高,不建议用