饿汉模式

线程安全,调用效率高,但是不能延时加载

public class Singleton1 {

    private static final Singleton1 instance = new Singleton1();

    private Singleton1(){}

    public static Singleton1 getInstance(){
        return instance;
    }
}

懒汉模式

线程不安全,会产生多个实例

public class Singleton2 {

    private static Singleton2 instance;
    private Singleton2(){}
    public static Singleton2 getInstance(){
        if (instance == null){
            instance = new Singleton2();
        }
        return instance;
    }
}

getInstance()方法加锁(效率低)

public class Singleton3 {

    private static Singleton3 instance;

    private Singleton3(){}

    public synchronized static Singleton3 getInstance(){
        if (instance == null){
            instance = new Singleton3();
        }
        return instance;
    }
}

双重检测锁模式

由于指令重排序问题,偶尔会出现异常,比如构造方法里面有大量的操作,jvm可能不会等到所有的操作都执行完,才返回实例指针

public class Singleton4 {

    private static Singleton4 instance;

    private Singleton4() {}

    public static Singleton4 getInstance() {
        if (instance == null) {
            synchronized (Singleton4.class) {
                if (instance == null) {
                    instance = new Singleton4();
                }
            }
        }
        return instance;
    }
}

  

5、双重检测锁模式2

通过volatile解决【4】的问题,严格要求happen before,也就是在执行【读】操作的时候必须看到完整的【写】操作

public class Singleton5 {

    private static volatile Singleton5 instance;

    private Singleton5() {}

    public static Singleton5 getInstance() {
        if (instance == null) {
            synchronized (Singleton5.class) {
                if (instance == null) {
                    instance = new Singleton5();
                }
            }
        }
        return instance;
    }
}

6、静态内部类

懒加载、线程安全、效率高

public class Singleton6 {

    private Singleton6() {}

    private static class InstanceHolder {
        private static final Singleton6 instance = new Singleton6();
    }

    public static Singleton6 getInstance() {
        return InstanceHolder.instance;
    }
}

7、枚举

枚举是线程安全的,而且只会被装载一次

public class Singleton7 {

    private enum Singleton {
        INSTANCE;
        private final Singleton7 instance;

        Singleton() {
            instance = new Singleton7();
        }

        public Singleton7 getInstance() {
            return instance;
        }
    }

    public static Singleton7 getInstance(){
        return Singleton.INSTANCE.getInstance();
    }
}

  

03-08 04:36