你需要记住的单例模式

单例模式有很多种实现方式,网上资料也有很多,什么枚举型、饿汉型、懒汉型、静态内部类型等等,实现方式很多,不便于记忆。我总结了一下,你需要记住两种类型,即线程安全型和非线程安全型。如有瑕疵,望不吝赐教。

线程安全型:

public class SingletonThreadSafe {

    //私有化构造器
    private SingletonThreadSafe(){}

    public static SingletonThreadSafe getInstance(){
        return SingletonHolder.INSTANCE;
    }

    //静态内部类
    private static class SingletonHolder{
        private static final SingletonThreadSafe INSTANCE = new SingletonThreadSafe();
    }
}

非线程安全型:

public class SingletonThreadUnsafe {

    private static SingletonThreadUnsafe unsafe = null;

    //私有化构造器
    private SingletonThreadUnsafe(){}

    public static SingletonThreadUnsafe getInstance(){
        if (null == unsafe){
            unsafe = new SingletonThreadUnsafe();
        }
        return unsafe;
    }

}

这两种方式都是懒加载式的,只有在真正使用的时候才会初始化instance,对系统友好。对于非线程安全的单例是懒加载的比较好理解,但上面那种线程安全的单例是懒加载的可能有疑问,可以通过下面的例子验证:

public class SingletonThreadSafe {

    //私有化构造器
    private SingletonThreadSafe(){
        System.err.println("主类调用了");
    }

    public static SingletonThreadSafe getInstance(){
        return SingletonHolder.INSTANCE;
    }

    public static void printString(){
        System.err.println("主动调用了printString方法");
    }

    //静态内部类
    private static class SingletonHolder{
        private static final SingletonThreadSafe INSTANCE = new SingletonThreadSafe();
        static {
            System.err.println("静态内部类被初始化了");
        }
    }

    public static void main(String[] args) {
        SingletonThreadSafe.printString();
//        SingletonThreadSafe instance = SingletonThreadSafe.getInstance();
    }
}

分别执行main函数内的方法,即可看到效果$_$。

你可能感兴趣的:(Java)