《《仅供自己观看!!!》》
昨天刚刚看了一下关于单例模式的书《研磨设计模式》,很棒的一本书!
-----------------------------------朕是分割线-----------------------------------
关于单例模式,总体来说分为懒汉式和饿汉式,当然,饿汉式更加简单,比较单调。
public class Singleton { private static final Singleton singleton = new Singleton(); private Singleton() { } public static Singleton getInstance() { return singleton; } }
这种就是简单的饿汉式的模板,最重要的思想就是控制了实例只能new一个,通过对构造函数的控制,不能随便new出实例,只能通过调用getInstance()方法得到实例,因为static是共享同一内存区域的。
懒汉式:
public class Singleton { private volatile static final Singleton singleton = null; private Singleton() { } public static Singleton getInstance() { if (singleton== null) { synchronized (Singleton.class) { if (singleton== null) { singleton= new Singleton(); } } } return singleton; } }
这种方法叫做double-check 双重检查,其中,被volatile修饰的变量的值将不会被本地线程缓存,所以对该变量的读写都是直接操作共享内存,从而使多线程正确处理该变量。如果你只使用第一个if()去判断实例是否已经存在,那么就可能在多线程情况下出现错误,还是可能导致多实例
public class Singleton { private static final Singleton singleton = null; private Singleton() { } public static Singleton getInstance() { if (singleton== null) { singleton= new Singleton(); } return singleton; } }
因为在多线程情况下,两个线程都进入if()中这是很有可能发生的,然后我们期望的单例就破灭啦!!!
所以还是用上面的double-check吧!
当然,在Java中还有一种更好的单例实现方式,既能实现延迟加载、又能实现线程安全!!!
肯定是有的,它利用的是Java中的静态初始化类,让JVM保证线程安全
public class Singleton { private volatile static final Singleton singleton = null; private Singleton() { } /* *静态初始化器,由JVM保证线程安全 */ private static class SingletonHolder{ private static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }
至于这里面后续的缓存和延迟加载,待续....