singleton 单例模式

单例模式是Java 中最常用的设计模式,也是面试中经常考察的。

标准版本

<图解设计模式> 书本上的示例代码,在class内有一个静态的变量直接赋值,在类加载的时候就初始化。缺点是有点浪费内存。因为类加载的时候是单线程,保证单例和线程安全。

public class Singleton1 {
      private static Singleton1 singleton1 = new Singleton1();
      private Singleton1() {
            System.out.println("生成了一个实例.");
      }
      public static Singleton1 getInstance() {
            return singleton1;
      }
}

synchronized

延迟初始化实例,但是为了保证线程安全,getInstance需要加锁。

public class Singleton2 {
      private static Singleton2 singleton2 = null;
      private Singleton2() {
            System.out.println("生成了一个实例.");
      }
      public static synchronized Singleton2 getInstance() {
            if (singleton2 == null){
                  singleton2 = new Singleton2();
            }
            return singleton2;
      }
}

双重校验

在方法上加锁synchronized,效率比较低,为了提高效率在getInstance方法内部加锁。锁住的代码范围越小,所等待的时间越少。

public class Singleton3 {
    private static Singleton3 instance = null;
    private Singleton3() {
        System.out.println("生成了一个实例.");
    }
    public static Singleton3 getInstance() {
        if (instance == null){
            synchronized (Singleton3.class){
                if (instance == null) {
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }
}

利用静态内部类

这种方式同样利用了 classloder 机制来保证初始化 instance 时只有一个线程,它跟标准版本不同的是:标准版本只要 Singleton 类被装载了,那么 instance 就会被实例化(没有达到 lazy loading 效果),而这种方式是 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有显示通过调用 getInstance 方法时,才会显示装载 SingletonHolder 类,从而实例化 instance。想象一下,如果实例化 instance 很消耗资源,所以想让它延迟加载,另外一方面,又不希望在 Singleton 类加载时就实例化,因为不能确保 Singleton 类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化 instance 显然是不合适的。这个时候,这种方式相比标准版本就显得很合理。

public class Singleton4 {
    private static class SingletonHolder {
        private static final Singleton4 INSTANCE = new Singleton4();
    }
    private Singleton4 (){}
    public static final Singleton4 getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

openmartin
71 声望3 粉丝

古典占星 。师从台湾杨国正老师。|| 占星看盘请私信。|| 伟大的灵魂都是雌雄同体 || 开放心态,契约精神