设计模式——单例模式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 1、定义
  • 2、结构
  • 3、常见应用
    • [3.1 懒汉式与饿汉式单例](#3.1 懒汉式与饿汉式单例)
      • [3.1.1 懒汉式单例](#3.1.1 懒汉式单例)
      • [3.1.2 饿汉式单例](#3.1.2 饿汉式单例)
    • [3.2 双重检验锁实现单例模式](#3.2 双重检验锁实现单例模式)
  • 总结

前言

对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。


1、定义

模式定义:

  • 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。
  • 单例模式的要点有3个:一是某个类子能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。单例模式是一种对象创建型模式。

优点:

  • 提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它,并为设计及开发团队提供了共享的概念。
  • 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。
  • 允许可变数目的实例。我们可以基于单例模式进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例。

2、结构

3、常见应用

3.1 懒汉式与饿汉式单例

  • 饿汉式单例在自己被加载时就将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,则比懒汉式单例类稍好些。
  • 懒汉式单例在实例化时,必须处理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必须涉及资源初始化,而资源初始化很有可能耗费大量时间,这意味着出现多线程同时首次引用类的几率变得较大,需要通过同步机制进行控制。

3.1.1 懒汉式单例

java 复制代码
public class Singleton1 {

    Singleton1(){}

    private static Singleton1 instance = null;

    public static Singleton1 getInstance() {
        if(instance == null){
            instance = new Singleton1();
        }
        return instance;
    }
}

3.1.2 饿汉式单例

java 复制代码
public class Singleton2 {

    private static Singleton2 instance = new Singleton2();

    private Singleton2(){}

    public static Singleton2 getInstance() {
        return instance;
    }
}

3.2 双重检验锁实现单例模式

java 复制代码
public class Singleton3 {

    private volatile static Singleton3 uniqueInstance = null;

    private Singleton3(){}

    public static Singleton3 getUniqueSingleton() {
        if(uniqueInstance == null){
            synchronized (Singleton3.class){
                if(uniqueInstance == null) {
                    uniqueInstance = new Singleton3();
                }
            }
        }
        return uniqueInstance;
    }
}

两个问题:

  • 为什么要使用双重检验锁
    • 锁竞争会有开销,所以需要在外层判断一下,如果已经创建了实例,直接返回实例即可。
    • 如果内层不添加if判断语句的话,在多线程环境下,如果有多个线程竞争锁,则会创建多个实例对象。
  • 为什么要用volatile关键字
    • JVM中会出现指令重排的现象,uniqueInstance = new Singleton3() 实际上分3步执行:1、为uniqueInstance分配内存空间,2、初始化uniqueInstance,3、将uniqueInstance指向分配的内存地址。
    • 这个时候如果发生指令重排的话,则可能未初始化完成uniqueInstance就通过外层条件判断语句返回实例对象。

总结

相关推荐
折哥的程序人生 · 物流技术专研6 小时前
第4篇:Lambda 简化策略模式(Java 8+)
java·设计模式·策略模式·函数式编程·lambda·代码简化·扩充系列
jsonbro13 小时前
手把手带你实现发布订阅模式
前端·vue.js·设计模式
workflower14 小时前
室内外配送机器人-应用路径
人工智能·机器学习·设计模式·矩阵·自动化
ttod_qzstudio20 小时前
【软考设计模式】原型模式:“克隆“对象与深拷贝、浅拷贝精讲
设计模式·原型模式
geovindu20 小时前
java: Builder Pattern
java·开发语言·后端·设计模式·建造者模式·生成器模式
researcher-Jiang1 天前
Design Patterns——Template Method入门到情景实战
python·设计模式·模板方法模式
饼干哥哥2 天前
用Claude Code跑通跨境电商的5大场景,顶10个人的团队
人工智能·设计模式·正则表达式
折哥的程序人生 · 物流技术专研2 天前
第3篇:手写促销策略引擎(满减、打折、立减)
java·设计模式·策略模式·开闭原则·编程实战·扩充系列·促销引擎
折哥的程序人生 · 物流技术专研2 天前
第3篇:手写一个饮品制作模板(附代码)
java·设计模式·行为型模式·模版方法模式·钩子方法·代码复用·编程实战
ttod_qzstudio2 天前
【软考设计模式】单例模式:唯一实例的管控与线程安全精讲
单例模式·设计模式