单例模式向系统外界提供了唯一的自身对象,外界无法自行创建一个单例的对象。由于单例模式代码简短,经常会出现在面试笔试题目之中。单例模式分为“饿汉式”和“懒汉式”两种,下面分别展示两种。

饿汉式:在初始化的时候就创建实例

public class Singleton{
    private static final Singleton singleton=new Singleton();
    private Singleton(){
    
    }
    public static Singleton getInstance(){
        return singleton;
    }
}

懒汉式:在外部调用共有服务方法时才判断是否需要创建

public class SingletonLazyload{
    private static SingletonLazyload singleton;
    private SingletonLazyload(){
    
    }
    public static SingletonLazyload getInstance(){
        if(singleton==null){
            singleton=new SingletonLazyload();
        }
        return singleton;
    }
}

懒汉模式有个问题,在多线程下,这个程序容易发生错误,可能会有两个线程试图访问其getInstance方法。改进方法是用同步的方法,用法如下:

public class SingletonLazyloadSyn{
    private static SingletonLazyloadSyn singleton;
    private SingletonLazyloadSyn(){
    
    }
    public static synchronized SingletonLazyloadSyn getInstance(){
        if(singleton==null){
            singleton=new SingletonLazyloadSyn();
        }
        return singleton;
    }
}

另一种能够保证线程安全的方法利用了Java虚拟机的特性。方法如下:

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

单例模式还有双重检查模式DCL,但是不推荐使用,需要用到volatile关键字修饰。