概述
这种模式设计到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象方式,可以直接访问,不需要实例化该类的对象。
单例模式的实现
- 饿汉式:即类的初始化阶段就创建单例对象
package com.syn.single;public class Hungry {/*构造方法私有化*/private Hungry(){}/*类中创建对象*/private static Hungry hungry = new Hungry();/*提供给外界获取对象的窗口*/public static Hungry getInstance(){return hungry;}
}
- 懒汉式:首次被调用时才创建单例对象
package com.syn.single;public class Lazy {/*私有构造方法*/private Lazy(){};/*声明单例变量*/private static Lazy lazy;/*对外提供方法,并加上同步锁*/public static synchronized Lazy getInstance(){if (lazy == null) {lazy = new Lazy();}return lazy;}
}
- 懒汉式-双重检查方式:
package com.syn.single;public class LazyDouCheck {/*私有构造方法*/private LazyDouCheck(){};/*声明单例变量*/private static volatile LazyDouCheck lazyDouCheck;/*对外提供方法,并加上同步锁*/public static LazyDouCheck getInstance(){/*第一次判断,如果部位null,则直接返回已创建的单例对象*/if (lazyDouCheck == null) {/*此处锁住类*/synchronized (LazyDouCheck.class){/*抢到锁之后再次判断是否为null*/if (lazyDouCheck == null){lazyDouCheck = new LazyDouCheck();}}}return lazyDouCheck;}
}
- 饿汉式(恶汉式)- 枚举类:
package com.syn.single;public enum Evil {INSTANCE;
}
破坏单例模式解决方案
1.序列化与反序列化破坏解决
package com.syn.single;public class Lazy {/*私有构造方法*/private Lazy(){};/*声明单例变量*/private static Lazy lazy;/*对外提供方法,并加上同步锁*/public static synchronized Lazy getInstance(){if (lazy == null) {lazy = new Lazy();}return lazy;}/*反序列化时被调用,如果定义了这个方法,就返回这个方法的值,反之则new新对象*/public Object readResolve(){return Lazy.lazy;}
}
2.反射破坏解决
package com.syn.single;public class Lazy {private static boolean flag = false;/*私有构造方法*/private Lazy(){/*处理多线程问题*/synchronized (Lazy.class){/*根据flag判断对象是否已经创建*/if (false){throw new RuntimeException("不能创建多个对象");}flag = true;}};/*声明单例变量*/private static Lazy lazy;/*对外提供方法,并加上同步锁*/public static synchronized Lazy getInstance(){if (lazy == null) {lazy = new Lazy();}return lazy;}
}