美文网首页
设计模式之单例模式

设计模式之单例模式

作者: Tinyspot | 来源:发表于2023-02-12 22:00 被阅读0次

    1. 单例模式(Singleton)

    • 一个类只有一个实例, 并提供一个访问该实例的全局节点
    • 应用
      • ServletContext
      • ApplicationContext

    2. 实战

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Singleton.getInstance().hashCode());
                }
            }).start();
        }
    }
    

    2.1 饿汉式

    • 类加载时创建,天生线程安全,以空间换时间
    • 优点:线程安全
    • 缺点:生命周期太长,浪费空间(不使用也会创建)
    public class Singleton {
        // final 常量, 私有构造方法
        private static final Singleton instance = new Singleton();
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            return instance;
        }
    }
    

    2.2 懒汉式

    • 使用时创建,线程不安全,需加同步
    • 优点:生命周期短,节省空间
    • 缺点:有线程安全问题(用同步)
    public class Singleton {
        private static Singleton instance = null;
    
        private Singleton() {}
        
        public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }
    

    改进:双重校验锁

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

    2.3 静态内部类写法(也是懒汉式)

    public class Singleton {
        private static Singleton instance = null;
    
        private static class Holder {
            static Singleton singleton = new Singleton();
        }
    
        public static Singleton getInstance() {
            return Holder.singleton;
        }
    }
    

    优点:外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化instance,不占内存
    只有当 getInstance() 第一次被调用时,才会去初始化INSTANCE,第一次调用getInstance()方法会导致虚拟机加载SingleTonHoler类,这种方法不仅能确保线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。

    2.4 容器式单例

    容器式单例写法适用于需要大量创建单例对象的场景,便于管理,但它是非线程安全的

    public class ContainerSingleton {
    
        private static Map<String, Object> beanMap = new ConcurrentHashMap<>();
    
        private ContainerSingleton() {
    
        }
    
        public static Object getBean(String className) {
            synchronized (beanMap) {
                if (beanMap.containsKey(className)) {
                    return beanMap.get(className);
                } else {
                    Object obj = null;
                    try {
                        obj = Class.forName(className).newInstance();
                        beanMap.put(className, obj);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return obj;
                }
            }
        }
    }
    

    扩展:Spring中的容器式单例
    Spring中的 Bean 默认是单例模式的,框架并没有对bean进行多线程的封装处理,Bean 是全局共享的,所以不是线程安全的
    若需要线程安全的 Bean, 改变 Bean 的作用域 把 "singleton" 改为 "protopyte"

    相关文章

      网友评论

          本文标题:设计模式之单例模式

          本文链接:https://www.haomeiwen.com/subject/oqtjkdtx.html