单例模式

单例模式:一个对象只有一个实例

在多线程中,会有线程安全的问题,所以出现了饿汉模式和懒汉模式

饿汉模式

/**
 * 饿汉模式
 * 单例模式在类装载时进行创建
 */
public class App {

    private App(){

    }
    private static App singletonIntance = new App();

    public static App getSingleInstance(){
        return singletonIntance;
    }
    public static void main(String[] args) {
        App example1 = App.getSingleInstance();
        App example2 = App.getSingleInstance();
        App example3 = new App();

        System.out.println(example1 + ":" + example2 + ":" + example3);
        //cout:   App@3f3afe78:App@3f3afe78:App@880ec60
    }
}

懒汉模式

/**
 * 懒汉模式 -》 双重同步锁单例模式
 * 单例实例在第一次使用时进行创建
 */
public class App {

    private App(){

    }

    /**
     * // 1、memory = allocate() 分配对象的内存空间
     *     // 2、ctorInstance() 初始化对象
     *     // 3、instance = memory 设置instance指向刚分配的内存
     *
     *     // JVM和cpu优化,发生了指令重排
     *
     *     // 1、memory = allocate() 分配对象的内存空间
     *     // 3、instance = memory 设置instance指向刚分配的内存
     *     // 2、ctorInstance() 初始化对象
     */
    //加入volatile防止指令重排序,
    //第3步之前,若有程序到了判断singletonIntance == null则会出错
    private volatile static App singletonIntance = null;

    public static App getSingleInstance(){
        //双重检测机制
        if(singletonIntance == null) {
            synchronized (App.class) { //同步锁

                //怕上面那一步在上锁之前且判断singletonIntance为空之后创建了实例
                if(singletonIntance == null) {
                    singletonIntance = new App();
                }
            }
        }
        return singletonIntance;
    }
    public static void main(String[] args) {
        App example1 = App.getSingleInstance();
        App example2 = App.getSingleInstance();
        App example3 = new App();

        System.out.println(example1 + ":" + example2 + ":" + example3);
        //cout:   App@3f3afe78:App@3f3afe78:App@880ec60
    }
}