参考连接:html
http://www.runoob.com/design-pattern/singleton-pattern.htmljava
一个类只有一个实例,每次都返回相同实例安全
须要控制实例数目时可选择使用该模式,建议使用静态内部类实现,只有在调用getInstance时才实例化,实现了Lazy初始化,也是多线程安全。利用classloader机制保证初始化instance时只有一个线程。多线程
单俐对象每每存在于DAO层,例如SessionFactory函数
在内存中只有一个实例,减小内存开销。spa
/** * Created by liang on 2018/5/8. */ public class SingletonDemo { private static SingletonDemo instance; // 构造函数私有化 private SingletonDemo() {} public static SingletonDemo getInstance() { if (instance == null) { instance = new SingletonDemo(); } return instance; } }
/** * 线程安全的单俐模式实现 * Created by liang on 2018/5/8. */ public class ThreadSafeSingletonDemo { private static ThreadSafeSingletonDemo instance; private ThreadSafeSingletonDemo() {} public static synchronized ThreadSafeSingletonDemo getInstance() { if (instance == null) { instance = new ThreadSafeSingletonDemo(); } return instance; } }
/** * 使用静态内部类 * 在调用getInstance()时才加载该单俐类,这种方法也是线程安全的 * Created by liang on 2018/5/8. */ public class StaticInnerClassSingletonDemo { private static class SingletonHolder { private static StaticInnerClassSingletonDemo instance = new StaticInnerClassSingletonDemo(); } private StaticInnerClassSingletonDemo() {} public static StaticInnerClassSingletonDemo getInstance() { return SingletonHolder.instance; } }
/** * 双重锁校验 * Step 1: 线程A访问getInstance()方法,由于单俐尚未实例化,因此进入了锁定块 * Step 2: 线程B访问getInstance()方法,得以访问接下来的代码块,而接下来代码块已经被线程A锁定 * Step 3: 线程A进入下一判断,由于单俐尚未实例化,因此进行单俐实例化,成功实例化后退出代码块,解除锁定 * Step 4: 线程B进入接下来的代码块,锁定线程,进入下一判断,由于已经实例化,退出代码块,解除锁定。 * Step 5: 线程A获取到了单俐实例并返回,线程B没有获取到单俐返回Null * Created by liang on 2018/5/8. */ public class DoubleValidateSingletonDemo { // 每次都返回最新的值 private volatile static DoubleValidateSingletonDemo instance; private DoubleValidateSingletonDemo() {} public static DoubleValidateSingletonDemo getInstance() { if (instance == null) { synchronized (DoubleValidateSingletonDemo.class) { if (instance == null) { instance = new DoubleValidateSingletonDemo(); } } } return instance; } }