单例模式

…衆ロ難τιáo~ 提交于 2019-12-05 04:32:23
/**
 * 饿汉式 在类初始化时直接创建对象,不存在线程安全问题,不管你是否需要这个对象都会创建
 * <p>
 * 1. 构造器私有化
 * 2. 自行创建,并且用静态变量保存
 * 3. 向外提供这个实例
 * 4. 强调这是一个单例,我们可以用final修饰,不能改变引用,可以改变属性。
 *
 * @author yuan
 */
public class Singleton1 {
    public static final Singleton1 INSTANCE = new Singleton1();

    private static Date date = new Date();

    private Singleton1() {

    }
}
/**
 * 饿汉式
 * <p>
 * 枚举类型:表示该类型的对象是有限的几个
 * 我们可以限定成一个,就成了单例
 * <p>
 * public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE };
 * 实际上,这个声明定义的类型是一个类,它刚好有四个实例,在此尽量不要构造新对象。
 * https://www.cnblogs.com/liaojie970/p/6474733.html
 *
 * @author yuan
 */
public enum Singleton2 {
    /**
     * 相当于 Singleton2 INSTANCE = new Singleton2()
     * 反编译可以看到这个类的构造函数是私有的: private Singleton2() {}
     */
    INSTANCE
}
package com.yuan.middleware.base.design.single;

import lombok.Data;

import java.io.IOException;
import java.util.Properties;

/**
 * 饿汉式
 * <p>
 * 静态代码块饿汉式,也是线程安全的
 * 适合于需要灵活初始化属性
 *
 * @author yuan
 */
@Data
public class Singleton3 {
    public static final Singleton3 INSTANCE;

    private String info;

    static {
        Properties pro = new Properties();
        try {
            //通过类加载器加载配置文件,需要特别注意文件路径否则NullPointerException
            pro.load(Singleton3.class.getClassLoader().getResourceAsStream("single.properties"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        INSTANCE = new Singleton3(pro.getProperty("info"));
    }

    private Singleton3(String info) {
        this.info = info;
    }
}
package com.yuan.middleware.base.design.single;

/**
 * 懒汉式
 * 延迟创建这个实例对象
 * 1. 构造器私有化
 * 2. 用一个静态变量保存这个唯一的实例
 * 3. 提供一个静态方法,获取这个实例对象
 *
 * @author yuan
 */
public class Singleton4 {
    private static Singleton4 instance;

    private Singleton4() {

    }

    /**
     * 线程不安全
     *
     * @return
     */
    public static Singleton4 getInstance() {
        if (instance == null) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new Singleton4();
        }
        return instance;
    }
}
package com.yuan.middleware.base.design.single;

/**
 * 懒汉式
 * 延迟创建这个实例对象
 * 1. 构造器私有化
 * 2. 用一个静态变量保存这个唯一的实例
 * 3. 提供一个静态方法,获取这个实例对象
 *
 * @author yuan
 */
public class Singleton5 {
    private static Singleton5 instance;

    private Singleton5() {

    }

    /**
     * 线程安全
     *
     * @return
     */
    public static Singleton5 getInstance() {
        if (instance == null) {
            synchronized (instance) {
                if (instance == null) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new Singleton5();
                }
            }
        }
        return instance;
    }
}
package com.yuan.middleware.base.design.single;

/**
 * 懒汉式
 * 在内部类被加载和初始化时,才创建INSTANCE实例对象
 * 静态内部类不会自动随着外部内的加载和初始化而初始化,它是需要单独去加载和初始化的
 * 因为是在内部类加载和初始化时,创建的,因此是线程安全的
 * <p>
 * JVM必须确保一个类在初始化的过程中,如果是多线程需要同时初始化它,仅仅只能允许其中一个线程对其执行初始化操作,
 * 其余线程必须等待,只有在活动线程执行完对类的初始化操作之后,才会通知正在等待的其他线程。
 *
 * @author yuan
 */
public class Singleton6 {
    private Singleton6() {
    }

    private static class Inner {
        private static final Singleton6 INSTANCE = new Singleton6();
    }

    public static Singleton6 getInstance() {
        return Inner.INSTANCE;
    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!