设计模式之单例模式

饿汉模式

即使我们不需要使用当前实例,饿汉模式也会生成实例,如果该实例占用内存过大,那么将是一个浪费。

public class Singleton {
    private static volatile Singleton instance = new Singleton();
 
    // 私有构造方法,防止实例化
    private Singleton() {
    }
 
    public static Singleton getInstance() {
        return instance;
    }
}

懒汉模式

延迟初始化,只有在需要的时候才生成对象,这是饿汉模式所带来的好处。

双重检查

public class LazySingleton {
    private static volatile LazySingleton instance = null;
 
    // private constructor
    private LazySingleton() {
    }
 
    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                // 双重检查 防止并发情况下同时进入if语句
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

使用静态代码块

public class StaticBlockSingleton {
    private static final StaticBlockSingleton INSTANCE;
 
    static {
        try {
            INSTANCE = new StaticBlockSingleton();
        } catch (Exception e) {
            throw new RuntimeException("Uffff, i was not expecting this!", e);
        }
    }
 
    public static StaticBlockSingleton getInstance() {
        return INSTANCE;
    }
 
    private StaticBlockSingleton() {
        // ...
    }
}

这段代码的问题是如果一个类中有多个静态变量,那么访问启动一个变量的时候,将初始所有的静态代码块。

使用静态内部类

public class BillPughSingleton {
    private BillPughSingleton() {
    }
 
    //这个静态内部类在没有使用之前不会初始化 ,即使你访问了其他的静态成员
    private static class LazyHolder {
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }
 
    public static BillPughSingleton getInstance() {
        return LazyHolder.INSTANCE;
    }
}

这种模式解决了上诉的问题,它达到按需加载的效果!

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

人生中没有四季 唯有那寒冬的荒野