单例模式的概述
单例模式,就是在应用中确保某个对象只能存在一份。
主要办法就是把类的构造函数私有化,提供一个私有静态的变量,并提供一个静态方法获取单例对象。
5种创建单例模式的方法
1.懒汉模式(非线程安全)
这种模式创建在多线程情况下,存在初始化多个对象的情况,例如:A线程执行了lazyPattern == null之后sleep了,线程B进入后发现lazyPattern == null,于是B初始化一个对象,A线程获取运行权限之后,继续初始化了一个对象。相当于初始化了两次。

2.懒汉模式(线程安全)
synchronized的目的是在同一时间里,只允许有一个线程进入getSimpleInstance方法,解决了线程问题,带来了效率问题。

3.双重检查创建单例,解决了上述在方法上加入synchronized带来的效率问题,仅在有需要的时候,在创建单例的代码块里加synchronized效率稍微好一点。在synchronized里面加第二个检查是因为防止多个线程在第一次获取单例对象时,同时执行完single==null,带来的线程安全问题,volatile是防止single变量,在分配内存,初始化,赋值的cpu执行顺序不一致导致的线程安全问题,其实jvm在运行代码时候会重新排序指令,cpu也会优化指令。

4.饿汉模式,解决了线程安全问题,带来的内存问题。不用的时候单例对象也占内存。饿汉模式中,静态变量定义时一般不建议调用一些方法。因为这种调用当出错时,调试和处理都比较异类。

5.静态内部类实现单例模式
这种方式在调用getUniqueInstance()的时候,才开始分配内存创建单例对象,挺好的办法。推荐。

6.Enum实现单例
Enum主要是通过虚拟机来管理对象的创建。该实现防止了反射来的安全问题。用类实现单例,可以通过反射拿到私有成员变量,创建对象。

网友评论