定义
确保每个类只存在一个实例,而且自行实例化并向整个系统提供这个实例
使用场景
访问IO,数据库,网络等需要消耗多资源的对象
实现方式
饿汉模式
这家伙太饥饿难耐啦,什么也不干,也不想想在多线程时候怎么保证单例对象的唯一性。
1 2 3 4 5 6 7 8 9 10 11 12
| public class HungrySingleton { private static final HungrySingleton hungrySingleton = new HungrySingleton(); private HungrySingleton(){} public static HungrySingleton getInstance(){ return hungrySingleton; } private Object readResolve() throws ObjectStreamException{ return hungrySingleton; } }
|
懒汉模式
这家伙懂事点点,考虑到多线程时候怎么保证单例对象的唯一性。就加个synchronized关键字嘛,每次调用该方法都进行同步,但是反应还是有点迟钝。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class LazySingleton { private static LazySingleton lazySingleton = null; private LazySingleton(){} /**偷懒! 只判断一次,造成每次调用该方法都进行同步*/ public static synchronized LazySingleton getInstance(){ if (lazySingleton == null){ lazySingleton = new LazySingleton(); } return lazySingleton; } /**防止反序列化重新构建对象*/ private Object readResolve() throws ObjectStreamException { return lazySingleton; } }
|
双重检查锁定
还是这家伙还是挺老实的,干活不怕苦不怕累,使用了两次判空操作,第一次判空防止不必要的同步,第二次判空保证在null情况下才创建实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class DCLSingleton { private static volatile DCLSingleton dclSingleton = null; private DCLSingleton(){} public static DCLSingleton getInstance(){ if (dclSingleton == null){ synchronized (DCLSingleton.class){ if (dclSingleton == null){ dclSingleton = new DCLSingleton(); } } } return dclSingleton; } private Object readResolve() throws ObjectStreamException { return dclSingleton; } }
|
静态内部类
这家伙比较靠谱了,既保证线程安全,也保证单例唯一性,又延迟了单例的实例化,mua
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class StaticInnerSingleton { private StaticInnerSingleton(){} public static StaticInnerSingleton getInstance(){ return StaticInnerSingleHolder.staticInnerSingleton; } private static class StaticInnerSingleHolder{ private static final StaticInnerSingleton staticInnerSingleton = new StaticInnerSingleton(); } /**防止反序列化重新构建对象*/ private Object readResolve() throws ObjectStreamException { return StaticInnerSingleHolder.staticInnerSingleton; } }
|
注意事项
以上实现方式,在反序列化时候会重新创建对象,所以必须加入以下方法
1 2 3 4
| /**防止反序列化重新构建对象*/ private Object readResolve() throws ObjectStreamException { return StaticInnerSingleHolder.staticInnerSingleton; }
|
总结
待更新…