菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
356
0

单例模式

原创
05/13 14:22
阅读数 28491

一、概述

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

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

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


二、单例的写法

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

“饿汉式”

  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的概念既保证了线程安全,又保证了效率。


 

三、总结

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

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

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

用一句话表述单例模式:

饿汉,懒汉,双重检验

发表评论

0/200
356 点赞
0 评论
收藏