单例模式 -- 懒汉模式&饿汉模式

2023-11-15

目录

一、单例模式是什么?

二、饿汉模式

三、懒汉模式

一、单例模式是什么?

单例模式是一种设计模式,用于将类的实例化限制为一个对象。它确保一个类只有一个实例,并提供了该实例的全局访问点。这种模式被广泛用于创建对象的唯一实例,例如数据库连接和日志记录器等。单例模式可以在多线程环境下使用,确保多个线程访问同一个实例时不会发生冲突。常见的实现方式包括懒加载、饿汉式和双重检查等。

二、饿汉模式

饿汉模式是一种单例模式的实现方式,它的特点是在程序启动时就进行对象的实例化。在这种实现方式中,单例对象会在类加载时就被创建出来,因此也被称作“饱汉模式”或者“静态常量方式”。

饿汉模式的优点是实现简单、线程安全,无需考虑多线程环境下的同步问题。其缺点是无法进行懒加载,带来了一定的系统资源开销。在某些场景下,如果单例对象很大或者初始化耗时较长,饿汉模式的开销可能会比较明显。

class Singleton{
    Singleton singleton = new Singleton();
    public Singleton getSingleton() {
        return singleton;
    }
    private Singleton(){}
}

三、懒汉模式

懒汉模式是一种单例模式的实现方式,它的特点是在首次访问单例对象时才进行对象的实例化。懒汉模式的优点是可以避免在程序启动时就进行对象的实例化,节省了系统的资源。懒汉模式的缺点是在多线程环境下,可能会出现线程安全问题,需要额外的同步措施来保证线程安全性。

例如,以下是一个简单的懒汉模式实现:

class Singleton{
    private static Singleton singleton = null;
    public Singleton getSingleton() {
        if (singleton==null){
            this.singleton = new Singleton();
        }
        return singleton;
    }
    private Singleton(){}
}
上面的懒汉模式的实现是线程不安全的.
线程安全问题发生在首次创建实例时. 在多个线程中同时调用 getSingleton 方法,可能两个线程会同时进行new操作 , 这样我们多线程创建了多个对象 , 就不是单例模式了 , 主要导致该问题的是由于这里面涉及到了对singleton的修改操作,失去了原子性,为了保证原子性,我们想到了加锁,从而实现线程安全问题。
我们为了解决这个多线程竞争的安全问题我们可以进行加锁操作 如下面代码
class Singleton{
    private static Singleton singleton = null;
    synchronized public Singleton getSingleton() {
        if (singleton==null){
            this.singleton = new Singleton();
        }
        return singleton;
    }
    private Singleton(){}
}

但是现在在我们进行 new 操作的时候可能会触发指令重排序 , 所以我们为了避免这个情况还需要对代码进行修改

class Singleton{
    volatile private static Singleton singleton = null;
     public Singleton getSingleton() {
         if (singleton==null){
             synchronized(Singleton.class){
                 if (singleton==null){
                     this.singleton = new Singleton();
                 }
             }
         }
         return singleton;
     }
    private Singleton(){}
}
  • 这里我们使用双if减少不必要的加锁操作
  • 加锁是为了把if和变成原子操作
  • 使用volatile禁止指令重排序
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单例模式 -- 懒汉模式&饿汉模式 的相关文章

  • linux常见面试题

    1 连接linux服务器工具有哪些 SecureCRSecureFX 最好 RealVNC SSHClient putty 比较 SecureCRSecureFX 可以文件传输 可使用命令行 设置字符编码 可开启多个 SSH Client

随机推荐

  • Java拾遗

    这里写自定义目录标题 Hibernate Error Unable to locate persister Caused by java lang NoClassDefFoundError javax sql rowset serial S
  • Nginx超时配置、限流

    目录 一 说明 二 超时配置 三 限流 限制访问频率 限制并发连接数 四 问题记录 五 参考文章 Author Jinwei EditTimes 2020年11月25日17 31 06 一 说明 Nginx 处理的每个请求均有相应的超时设置
  • spring注解及扩展

    1 spring配置注解 spring建议通过注解配置 替代原xml配置方式 使用配置类替代xml配置的优势大体 1 xml配置维护容易出错而且不易检查 java配置类基于java语法检查 对于java程序员更友好 易于维护 2 注解配置
  • NISEDIT如何发布,Qt如何发布文章?难道还有人不会(超详细教学,跟着走,不会你怪我)

    一 自动发布 直接运行即可 不过多阐述 二 手动发布 文件清单 ExamSys exe account txt exam txt Qt5Core dll Qt5Gui dll Qt5Widgets dll libstdc 6 dll lib
  • LeetCode中函数题中“多出来的参数“---returnsize

    转载 关于returnSize 第一次在leetcode上瞎逛就遇到了就遇到了它 int twoSum int nums int numsSize int target int returnSize 1 这个代码的实现并不是什么难解的方法
  • JVM 由哪些部分组成?

    JVM 由哪些部分组成 解析 这是对 JVM 体系结构的考察 答 JVM 的结构基本上由 4 部分组成 类加载器 在 JVM 启动时或者类运行时将需要的 class 加载到 JVM 中 执行引擎 执行引擎的任务是负责执行 class 文件中
  • Zynq7000硬件开发之芯片供电电源功耗(电流)评估

    案头语 单板硬件的主控芯片集成度越来越高 多核处理器越来越多 一块单板可能只需要1块芯片就能满足整体需求 一方面减少设计复杂度 另一面节省PCB面积成本 能同时掌握硬件原理设计以及PCB Layout设计逐渐成为主流 本系列文章同时包含有两
  • ES6详解 快速上手!

    一 Es6 1 1 ES6的概述 ECMAScript的快速发展 编程语言JavaScript是ECMAScript的实现和扩展 ECMAScript是由ECMA 一个类似W3C的标准组织 参与进行标准化的语法规范 ECMAScript定义
  • 【python量化】用python搭建一个股票舆情分析系统

    写在前面 下面的这篇文章将手把手教大家搭建一个简单的股票舆情分析系统 其中将先通过金融界网站爬取指定股票在一段时间的新闻 然后通过百度情感分析接口 用于评估指定股票的正面和反面新闻的占比 以此确定该股票是处于利好还是利空的状态 1 环境准备
  • C++(Liunx) 使用cut截 取出Ubuntu用户的家目录,要求:不能使用“:“作为分割.

    使用cut截 取出Ubuntu用户的家目录 要求 不能使用 作为分割
  • 43.MQ—RabbitMQ

    目录 一 MQ RabbitMQ 1 同步调用与异步调用 1 1 同步调用 1 2 异步调用 2 MQ之间的区别 3 RabbitMQ学习 3 1 docker下载rabbitmq容器 并启动 3 2 RabbitMQ中的几个概念 3 3
  • Python遥感开发之分段读取和保存遥感数据

    Python遥感开发之分段读取和保存遥感数据 1 分段读取数据 2 实现分批读取数据以及进行计算 3 实现分批保存成TIF文件 所有完整代码 4 分段TIF整合到一个TIF 5 生成一个空白TIF 每个像元值为0的TIF 前言 当遇到批量读
  • Supervisord进程管理工具的安装使用

    先来介绍 supervisord Supervisor 是一个进程监控程序 满足的需求是 我现在有一个进程需要每时每刻不断的跑 但是这个进程又有可能由于各种原因有可能中断 当进程中断的时候我希望能自动重新启动它 此时 我就需要使用到了 Su
  • dataloader的使用

    dataloader 构建可迭代的数据装载器 我们在训练的时候 每一个for循环 每一次iteration 就是从DataLoader中获取一个batch size大小的数据的 dataloader官网 torch utils data P
  • 【MySQL基础】常用函数

    文章目录 单行函数 字符函数 LENGTH CONCAT UPPER LOWER SUBSTR SUBSTRING INSTR TRIM LPAD RPAD REPLACE 数学函数 ABS ROUND CEIL FLOOR TRUNCAT
  • [每日两题系列]刷算法题咯~~

    今日题目 卡片 直线 本系列所选题目均来自力扣或者牛客网站 所选题目主要是以其中的简单题为主 中等题为辅 包含少数困难题 原因是 本人目前能力还不够 开展这个系列的目的是督促自己 在暑假的时间里也要保持有一定的刷题量 拒绝摆烂 话不多说 直
  • python矩阵教程_numpy教程:矩阵matrix及其运算

    numpy矩阵简介 NumPy函数库中存在两种不同的数据类型 矩阵matrix和数组array 都可以用于处理行列表示的数字元素 虽然它们看起来很相似 但是在这两个数据类型上执行相同的数学运算可能得到不同的结果 其中NumPy函数库中的ma
  • 插入MySQL数据库前去除重复数据的几种方法

    在数据存储过程中 可能会遇到数据主键重复的情况 我们可以通过下面几个方法进行处理 1 若数据不存在插入 存在更新 2 使用duplicate key关键字 如插入数据时发生主键冲突就更新数据 3 使用Ingore关键字 4 使用replac
  • BoxFit(缩放模式、自适应模式)

    类似于Android原生的ImageView ScaleType 以下是Flutter提供的Box缩放类型 fill Box被完全填充 相当于ScaleType的FIT XY contain 保持Box的纵横比至至少有一边填充满父控件 相当
  • 单例模式 -- 懒汉模式&饿汉模式

    目录 一 单例模式是什么 二 饿汉模式 三 懒汉模式 一 单例模式是什么 单例模式是一种设计模式 用于将类的实例化限制为一个对象 它确保一个类只有一个实例 并提供了该实例的全局访问点 这种模式被广泛用于创建对象的唯一实例 例如数据库连接和日