zoukankan      html  css  js  c++  java
  • 单例模式

    一、概述

    一般问题:有时候我们需要一个单一的全局对象,来协调系统整体的行为。

    核心方案:只允许此类有一个实例存在。

    设计意图:要让一个类只能有一个实例存在,首先要控制其构造方法,将其设为私有,使其只能在内部实例化。其次,提供一个静态方法,使外部可以通过此方法获取唯一实例。


    二、单例的写法

    单例模式的写法分为“饿汉式”和“懒汉式”,区别就是实例化的时机,一种是类加载时实例化;另一种是首次调用时实例化。

    “饿汉式”

      public class Singleton {
        
                //类加载时实例化
            private final static Singleton INSTANCE = new Singleton();
        
                //构造方法私有化
            private Singleton(){}
        
                //静态方法获取唯一实例
            public static Singleton getInstance(){
                return INSTANCE;
            }
        }

    这种写法比较简单,在类装载的时候就完成实例化,避免了线程同步问题。缺点是提前占用了内存,造成内存浪费。

    “懒汉式”

      public class Singleton {
        
            private static Singleton singleton;
        
            private Singleton() {}
        
            public static Singleton getInstance() {
                        //首次调用时实例化
                if (singleton == null) {
                    singleton = new Singleton();
                }
                return singleton;
            }
        }

    这种“懒汉式”写法起到了Lazy Loading的效果,但是只能在单线程下使用。如果在多线程下可能产生多个实例。

    “懒汉式”升级版

      public class Singleton {
        
            private static volatile Singleton singleton;
        
            private Singleton() {}
        
            public static Singleton getInstance() {
                if (singleton == null) {
                                //此处对代码块做线程同步,比直接对方法做线程同步更高效,因为只有首次实例化时起作用
                    synchronized (Singleton.class) {
                                        //这里双重判空(double-check)是必要的,否则依然可以产生多个实例
                        if (singleton == null) {
                            singleton = new Singleton();
                        }
                    }
                }
                return singleton;
            }
        }

    这种写法采用double-check的概念既保证了线程安全,又保证了效率。


    三、总结

    优点:减少内存开销,避免资源多重占用

    缺点:不能继承,扩展困难

    总结:单例模式是一种创建型设计模式,在对系统资源统一管理,化繁为简,避免“政出多头”方面有很好的优势。但我们不能仅仅为了节省资源而滥用单例模式。其保持单一实例必然还是为了达到用户特定的使用目的。比如有多个线程要同时进行文件创建、打开、修改一个文件的操作时,就用到单例模式设计文件管理器。

    用一句话表述单例模式:

    饿汉,懒汉,双重检验

  • 相关阅读:
    多线程
    事务的概念与四大特性(ACID)
    Error和Exception的区别
    运算符的使用与注意事项(二)
    运算符的使用与注意事项(一)
    GOJS使用--前端拓扑图
    python算法实现分治法demo
    MySQL主从复制配置
    MySQL锁
    show profile查看SQL执行生命周期
  • 原文地址:https://www.cnblogs.com/not2/p/10838974.html
Copyright © 2011-2022 走看看