单例模式详解
特点:
- 1、 保证从系统启动到系统终止, 全过程只会产生一个实例。
- 2、 当我们在应用中遇到功能性冲突的时候, 需要使用单例模式。
穷举法:
- 配置文件: 如果不是单例(针对于某一种功能的配置)
- Spring Context Factory 上下文
单例模式的七种写法:
- 懒汉式,需要用的时候才初始化
- 饿汉式,先实例化
- 注册登记式,相当于有个容器装在所有的实例,在实例产生之前先检查下容器看有没有,如果有就直接取出来,如果没有就先new一个放进去,然后给后面的人用,Spring IOC容器就是一种典型的注册登记单例。
七种单例模式:
/** * 懒汉式单例模式 * @author DoubleChina * @date 2018/1/6 11:51 */ public class Singleton { //1、第一步先将构造方法私有化,在反射面前,没用 private Singleton(){} //2、然后先声明一个静态变量保存单例的引用 private static Singleton singleton=null; //3、通过提供一个静态方法来获得单例的引用 public static Singleton getInstance(){ if (singleton==null){ singleton=new Singleton(); } return singleton; } }
/** * 懒汉式单例模式,保证线程安全 * @author DoubleChina * @date 2018/1/6 11:51 */ public class Singleton1 { //1、第一步先将构造方法私有化,在反射面前,没用 private Singleton1(){} //2、然后先声明一个静态变量保存单例的引用 private static Singleton1 singleton=null; //3、通过提供一个静态方法来获得单例的引用 //为了保证多行程环境下正确访问,给方法加上同步锁synchronized //存在一定的性能问题 public static synchronized Singleton1 getInstance(){ if (singleton==null){ singleton=new Singleton1(); } return singleton; } }
/** * 懒汉式单例模式,双重锁检查 * @author DoubleChina * @date 2018/1/6 11:51 */ public class Singleton2 { //1、第一步先将构造方法私有化,在反射面前,没用 private Singleton2() { } //2、然后先声明一个静态变量保存单例的引用 private static Singleton2 singleton = null; //3、通过提供一个静态方法来获得单例的引用 //为了保证多行程环境下正确访问,给方法加上同步锁synchronized //存在一定的性能问题 public static Singleton2 getInstance() { if (singleton == null) { synchronized (Singleton2.class) { if (singleton == null) { singleton = new Singleton2(); } } } return singleton; } }
/** * 最牛B的方式实现单例模式 * @author DoubleChina * @date 2018/1/6 11:51 */ public class Singleton4 { //2.声明一个静态内部类 private static class InnerClass { //final是为了防止内部将这个属性覆盖掉 private static final Singleton4 INSTANCE = new Singleton4(); } //1.先把构造方法私有化 private Singleton4() { } //3.提供获取实例方法 //防止子类重写父类方法 public static final Singleton4 getInstance() { return InnerClass.INSTANCE; } //内部类的初始化,需要依赖主类 //也就是说,当我们的JVM加载Singleton4类的时候,我们的InnerClass也同时被加载过来了 //目前还没有被实例化,需要等主类先实例化之后,内部类才开始实例化 //加final是为了防止子类重写父类方法 // }
/** * 饿汉式 * 单例模式,在类初始化,已经有自行的实例化 * @author DoubleChina * @date 2018/1/6 11:51 */ public class Singleton3 { //1、第一步先将构造方法私有化,在反射面前,没用 private Singleton3() { } //2、声明变量,在类实例化之前就初始化变量,将对象引用保存 private static final Singleton3 singleton = new Singleton3(); //3、开放静态方法,获取实例,但是占用内存空间 public static Singleton3 getInstance() { return singleton; } }
/** * 枚举式单例模式 * 不常用 * @author DoubleChina * @date 2018/1/6 11:52 */ public enum Singleton5 { INSTANCE; public void getInstance() { } }
/** * 登记式单例模式 * 类似Spring里面的方法,讲类名注册,下次从里面直接获取 * @author DoubleChina * @date 2018/1/6 11:52 */ public class Singleton6 { private static Map<String ,Singleton6> map=new ConcurrentHashMap<String, Singleton6>(); static { Singleton6 single=new Singleton6(); map.put(single.getClass().getName(),single); } //保护默认的构造函数 protected Singleton6(){} public static Singleton6 getInstance(String name){ if (name==null){ name=Singleton6.class.getName(); } if (map.get(name)==null){ try { map.put(name,(Singleton6)Class.forName(name).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return map.get(name); } }
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!