#单例模式学习
##饿汉式
public class SingleDemo { private static final SingleDemo s = new SingleDemo(); public static SingleDemo getInstance(){ return s; }}
##懒汉式
- 普通懒汉式
public class SingleDemo2 { private static SingleDemo2 s2; public static SingleDemo2 getInstance() { if (null == s2) { s2 = new SingleDemo2(); } return s2; }}
上面这种线程不安全
public class SingleDemo3 { private static SingleDemo3 s; public static synchronized SingleDemo3 getInstance(){ if(null == s){ s = new SingleDemo3(); } return s; }}
线程安全 耗时严重 同步getInstance()的方法既简单又有效。但是你必须知道,同步一个方法可能造成程序执行效率下降100倍。因此,如果getInstance()使用频繁的话,就需要考虑其他方法了.所以我们没有必要因空间而失去时间,在这个用户体验的时代不值得.
- double check 懒汉式
public class SingleDoubleCheck { private static SingleDoubleCheck s; public static SingleDoubleCheck getInstance() { if (null == s) { SingleDoubleCheck instance; synchronized (SingleDoubleCheck.class) { instance = s; if (null == instance) { synchronized (SingleDoubleCheck.class) { if (null == instance) { instance = new SingleDoubleCheck(); } } s = instance; } } } return s; }}
- 内部类懒汉式
public class SingleInnerClass { private static class InnerSingleClass{ private static final SingleInnerClass s = new SingleInnerClass(); } public static SingleInnerClass getInstance(){ return InnerSingleClass.s; }}
静态内部类 懒汉式 这周方式是利用了类加载的一些特性,在classloder的机制中,初始化instance时只有一个线程,而且这种方式还有一个好处就是起到了延时加 载的效果,当SingletonDemo4被加载了,但是内部类InnerSingleton并不会被加载,因为InnerSingleton没有主动使用,只有通过调用 getInstance方法时才会去加载InnerSingleton类,进而实例private static final SingletonDemo4 instance = new SingletonDemo4(); 因此这种巧妙的方式比起双重检查锁来说,安全来又高效了些.
##总结一下:
对于下面的单例总的来说各有各的优点,至于开发中使用哪个可以根据你的业务需求来选择.
####饿汉
- 标准饿汉 (安全防护方面 枚举单例更优于标准饿汉)
- 线程安全,高效,不可以懒加载
- 枚举单例
- 线程安全,高效,不可以懒加载(天然避免反射与反序列化)
- 懒汉 (效率方面 静态内部类更优于标准懒汉)
####标准懒汉
- 线程安全,低效,可以懒加载
- 双重检测(不推荐,有bug)
- 线程安全,低效,可以懒加载
- 静态内部类
- 线程安全,低效,可以懒加载