单例模式

单例模式Singleton

1.作用:保证整个应用程序中某个实例有且只有一个

2.应用场景:有些对象只需要一个就足够了,例如古代皇帝

3.类型:饿汉模式、懒汉模式、双重校验锁DCL(double checked locking)、静态内部类

1.饿汉模式 

//饿汉式
public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {
        return singleton;
    }
}

说明:饿汉式singleton这个实例是从Singleton这个类被加载后就被创建一直存在于内存中,如果我们一直不使用他就显的有点浪费内存了

2.懒汉模式

//懒汉式
public class Singleton {
    private static Singleton singleton;

    private Singleton() {

    }

    public synchronized static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

 说明:在方法上加锁可以解决线程并发问题,单同时解锁需要花费的时间也不少,导致性能下降

3.双重校验锁DCL(double checked locking)

//双重校验锁DCL(double checked locking)
public class Singleton {
    private static Singleton singleton;

    private Singleton() {

    }

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

说明:方法锁改成代码块锁,减少锁的范围提升性能;如果两个线程同时通过了第一个if条件,如果没有第二个if条件限制此时会创建两个singleton实例,所以两个if条件的验证是为了解决线程并发的情况

4.静态内部类

//静态内部类
public class Singleton {

    private Singleton() {

    }

    public static Singleton getInstance() {
        return SingletonHolder.singleton;
    }

    private static class SingletonHolder {
        private static Singleton singleton = new Singleton();
    }
}
说明当外部类Singleton被加载时,其静态内部类SingletonHolder不会被加载,所以他的成员变量singleton不会被实例化,只有当调用
Singleton.getInstance()方法时,才会加载SingletonHolder并且初始化其成员变量,而且类加载时是线程安全的,这样既保证了延迟加载
也保证了线程安全,同时也简化了代码量
原文地址:https://www.cnblogs.com/gyli20170901/p/9242320.html