单例模式是比较容易在面试中出现的问题,一般要求是手写代码,比如我就试过了。。所以一定要打起十二分精神,要了解线程安全的、效率高的单例模式怎么实现。下面是几个代码,分别是从不好的到好的逐渐递进,这样才能灵活面对面试官的下一步发问。好了,话不多说,直接上代码:
实现一:

public class Singletop1 {
    /*
     * SingleTop的解法1:
     * 推荐指数:***
     * 原因:只支持单线程环境
     * */
    private static Singletop1 instance = null;

    public static Singletop1 getSingletop1(){
        if (instance == null) {
            instance = new Singletop1();
        }
        //打印测试用例,可删除
        System.out.println(instance.hashCode());
        return instance;
    }
}

实现二:

public class SingleTop2 {
    /*
     * SingleTop的解法2:
     * 推荐指数:***
     * 原因:虽然在多线程环境中可以实现,但效率不高
     * */
    private static SingleTop2 instance2 = null;

    public static synchronized SingleTop2 getSingleTop2(){
        if (instance2 == null) {
            instance2 = new SingleTop2();
        }
        //打印测试用例,可删除
        System.out.println(instance2.hashCode());
        return instance2;
    }
}

实现三:

public class SingleTop3 {
    /*
     * SingleTop的解法3:
     * 推荐指数:****
     * 原因:适合多线程,效率可行,但结构复杂,不易理解
     * */
    private static Object synObject = new Object();
    private static SingleTop3 instance3 = null;

    public static SingleTop3 getSingleTop3(){
        if (instance3 == null) {
            synchronized (synObject) {
                if (instance3 == null) {
                    instance3 = new SingleTop3();
                }
            }
        }
        //打印测试用例,可删除
        System.out.println(instance3.hashCode());
        return instance3;
    }
}

实现四:

public class SingleTop4 {
    /*
     * SingleTop的解法4:
     * 推荐指数:****
     * 原因:线程安全,简洁,但效率同样较低,调用静态构造函数的时机不由程序员掌控
     * */
    private static final SingleTop4 instance4 = new SingleTop4();

    public static SingleTop4 getSingleTop4(){
        //打印测试用例,可删除
        System.out.println(instance4.hashCode());
        return instance4;
    }
}

实现五:

public class SingleTop5 {
    /*
     * SingleTop的解法5:
     * 推荐指数:*****
     * 原因:利用嵌套类型的特性,做到只有在真正需要的时候才创建实例,既线程安全,又节省资源
     * */
    public static SingleTop5 getSingleTop5(){
        //打印测试用例,可删除
        System.out.println(Nested.instance5.hashCode());
        return Nested.instance5;
    }

    private static class Nested{
        private static SingleTop5 instance5 = new SingleTop5(); 
    }
}

如果你认真看了一遍以上五种实现方式,是否发现他们都是为了解决前面某种不足而被开发出来的呢?这就是一种递进性的理解。如果你从第一个实现方式开始看起,知道第五个实现方式也掌握了的话,那你对单例模式的理解也就到火候了。当然,实现单例模式并不止这五种方法,还有其他的形式,比如利用枚举也可以实现。