6.单例模式

6.单例模式,第1张

6.单例模式

单例模式
  • 饿汉式单例
  • 懒汉式单例
  • 容器式单例
    • 枚举式单例
    • 注册式单例
    • 线程隔离式单例

单例模式属于创建型模式,用于在系统运行过程中保证只有一个实例。
创建单例面临的问题有:反射破坏单例,多线程并发破坏、序列化破坏单例

饿汉式单例
public class HungrySingleton {
    // 类加载时就初始化
    private static HungrySingleton hungrySingleton = new HungrySingleton();
    // 构造方法私有化
    private HungrySingleton(){
        // 防止反射破坏单例
        if (hungrySingleton != null) {
            throw new RuntimeException("非法访问");
        }
    }
    // 全局访问点
    public static HungrySingleton getInstance() {
        return hungrySingleton;
    }
    // 防止反序列化破环单例,ObjectInputStream桥接的方法。在反序列化时会调用readResolve方法返回单例
    public HungrySingleton readResolve() {
        return hungrySingleton;
    }
}
懒汉式单例
public class LazySingleton {
    // 加volatile,防止指令重排序问题。保证线程间可见性
    private volatile static LazySingleton lazySingleton;
    // 构造方法私有化
    private LazySingleton(){}
    // 静态方法方式:
    private static LazySingleton getInstance() {
        if (lazySingleton == null) {
            synchronized (LazySingleton.class) {
                if (lazySingleton == null) {
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}
public class LazyInnerSingleton {
    // 构造方法私有化
    private LazyInnerSingleton(){}

    public static LazyInnerSingleton getInstance() {
        return LazyInner.LAZY_INNER_SINGLETON;
    }
    // 静态内部类在使用时再加载,未使用时不浪费内存
    private static class LazyInner {
        private static final LazyInnerSingleton LAZY_INNER_SINGLETON = new LazyInnerSingleton();
    }
}
容器式单例

枚举式单例、注册式单例、线程隔离的单例

枚举式单例

Jdk提供的Enum类型

public enum EnumSingleton {
    INSTANCE;
    public static EnumSingleton getInstance() {
        return INSTANCE;
    }
}
注册式单例

spring的利用ioc容器存储单例的形式

public class IocSington {
    // 初始化一个容器,用于装载各种类的单例
    private static Map ioc = new HashMap<>();
    // 构造方法私有化
    private IocSington(){}
    // 根据需要的对象类型,获取对应的实例
    public static Object getInstance(Class clazz) {
        String name = clazz.getName();
        if (!ioc.containsKey(name)) {
            Constructor constructor = clazz.getConstructor(null);
            constructor.setAccessible(true);
            Object o = constructor.newInstance();
            ioc.put(name, o);
        }
        return ioc.get(name);
    }
}
线程隔离式单例

利用ThreadLocal类为每个线程提供线程间相互隔离的单例

public class ThreadLocalSingletion {
    private static final ThreadLocal threadLocal
            = new ThreadLocal(){
        @Override
        protected ThreadLocalSingletion initialValue() {
            return new ThreadLocalSingletion();
        }
    };
    private ThreadLocalSingletion(){}

    public static ThreadLocalSingletion getInstance() {
        return threadLocal.get();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5680960.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存