博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式——单例模式
阅读量:6279 次
发布时间:2019-06-22

本文共 3126 字,大约阅读时间需要 10 分钟。

阅读原文请访问我的博客

单例模式属于创建模型。

单例模式,是设计模式中比较简单而又最常用的模式之一。通过单例模式可以保证系统中,应用该模式的类只有一个类实例。例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。

模式定义

单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。

单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。

实现

1. 饿汉式

饿汉式提供了线程安全的单例,但是不支持懒加载,在第一次加载类到内存中时就会初始化(所以称之为饿汉,不管怎么样,先初始化了再说)。

/** * 饿汉式单例模式. * * @author BrightLoong. */public class Singleton {    /** 全局唯一实例. */    private static final Singleton singleton = new Singleton();    private Singleton() {}    public static Singleton getSingleton() {        return singleton;    }}复制代码

2. 非线程安全懒汉式

相对饿汉式,懒汉式提供了再需要时候初始化的方式,以下是非线程安全的实现方式,不建议使用。

/** * 非线程安全的懒汉式. * * @author BrightLoong. */public class Singleton {    private static Singleton singleton;    private Singleton() {}    /**     * 通过懒加载的方式获取实例,但是非线程安全.     * @return Singleton实例     */    public static Singleton getSingleton() {        if (singleton == null) {            singleton = new Singleton();        }        return singleton;    }}复制代码

3. 低效的线程安全懒汉式——使用synchronized

使用synchronized进行同步,虽然保证了线程安全,但是并不高效,比较单例模式只有在第一次创建的时候会存在线程安全问题,而不需要在创建单例后在以后的每一次调用还要进行同步。

/** * 低效的线程安全的懒汉式. * * @author BrightLoong. */public class Singleton {    private static Singleton singleton;    private Singleton() {}    /**     * 通过 synchronized 关键字来保证线程安全,也是懒加载的方式来获取实例.     * @return Singleton实例     */    public static synchronized Singleton getSingleton() {        if (singleton == null) {            singleton = new Singleton();        }        return singleton;    }}复制代码

4. 双重校验锁线程安全懒汉式

相对上面的同步方法,双重校验使用同步块解决线程安全问题。两次检查instance == null,一次是在同步块外,一次是在同步快内。为什么在同步块内还要检验一次,因为可能会有多个线程一起进入同步块外的if,如果在同步块内不进行二次检验的话就会生成多个实例了。

注:受限于Jdk5以前的Java内存模型,仍然会有bug,Java5及之后才能正常达到单例效果。

/** * 双重校验锁线程安全懒汉式. * * @author BrightLoong. */public class Singleton {    private static Singleton singleton;    private Singleton() {}    /**     * 通过'双重校验锁'来更高效的保证线程安全,也是懒加载的方式来获取实例.     * @return Singleton实例     */    public static Singleton getSingleton() {        if (singleton == null) {            synchronized (Singleton.class) {                if (singleton == null) {                    singleton = new Singleton();                }            }        }        return singleton;    }}复制代码

5. 枚举式

《Effective Java》一书中推荐使用枚举来实现单例模式,该方式简单可自由序列化;保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量),但是不支持懒加载。

/** * 枚举方式的单例. * * @author BrightLoong. */public enum Singleton {    INSTANCE;}复制代码

6. 静态内部类

使用JVM本身机制保证了线程安全问题,其只有显式通过调用getInstance方法时,才会装载SingletonHolder类,从而实例化instance;同时读取实例的时候不会进行同步,没有性能缺陷,也不依赖JDK版本。

/** * 通过使用静态内部类的方式来实现懒加载且线程安全的创建单例. * * @author BrightLoong. */public class Singleton {    private Singleton() {}    /**     * 静态内部类.     */    private static final class SingletonHolder {        private SingletonHolder() {}        private static Singleton4 instance = new Singleton();    }    /**     * 通过懒加载的方式获取Singleton唯一实例的方法.     * @return Singleton实例     */    public static Singleton getInstance() {        return SingletonHolder.instance;    }}复制代码

以上就是对单例模式的简单介绍,单例模式非常简单,其他的优缺点之类的不再赘述。

转载于:https://juejin.im/post/5add8e996fb9a07aaf34d160

你可能感兴趣的文章
正文提取算法
查看>>
轻松学PHP
查看>>
Linux中的网络监控命令
查看>>
this的用法
查看>>
windows下安装redis
查看>>
CentOS7 yum 安装git
查看>>
启动日志中频繁出现以下信息
查看>>
httpd – 对Apache的DFOREGROUND感到困惑
查看>>
分布式锁的一点理解
查看>>
idea的maven项目,install下载重复下载本地库中已有的jar包,而且下载后jar包都是lastupdated问题...
查看>>
2019测试指南-web应用程序安全测试(二)指纹Web服务器
查看>>
树莓派3链接wifi
查看>>
js面向对象编程
查看>>
Ruby中类 模块 单例方法 总结
查看>>
jQuery的validate插件
查看>>
5-4 8 管道符 作业控制 shell变量 环境变量配置
查看>>
Enumberable
查看>>
开发者论坛一周精粹(第五十四期) 求购备案服务号1枚!
查看>>
validate表单验证及自定义方法
查看>>
javascript 中出现missing ) after argument list的错误
查看>>