当前位置: 首页 > article >正文

设计模式2:单例模式

在这里插入图片描述

单例模式

单例模式属于创建型模式,⼀个单例类在任何情况下都只存在⼀个实例,
构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例,对外提供⼀
个静态公有⽅法获取实例。

双重检查锁(double check locking)

public class LazySingleton {
    //volatile防止指令重排序
    private static volatile LazySingleton instance;
    private LazySingleton() {}
    public static LazySingleton getInstance() {
        //第一次检查,确保不必要的同步
        if (instance == null) {
            synchronized (LazySingleton.class) {
                //第二次检查,确保只有一个线程创建实例
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}
  • 懒汉式,懒加载,使用的时候才创建对象

  • 双重检查指两次非空判断,锁指的synchronized加锁

    • 第一重判断,如果实例已经存在,无需进行同步操作
    • 第二重判断,有多个线程一起到达锁位置时,对锁竞争,其中一个线程获取锁后,第一次进入会判断实例为null,从而创建对象。完成后释放锁,其他线程获取锁后会被判定非空拦截,直接返回单例对象
  • synchronized同步代码块作用,防止有多个线程同时调用时,导致生成多个实例。有了同步块,每次只有1个线程能访问同步块内容。当第一个抢到锁线程创建实例后,之后的调用都不会进入同步块

  • volatile关键字作用:可见性、防止指令重排序。用new创建对象时,其实是三步操作,不是原子操作:

    • 1.在堆内存申请空间
    • 2.调用构造方法,初始化对象
    • 3.将引用变量指向堆内存空间

    为提高性能,处理器可能对代码执行顺序重新排序,如果运行顺序为1 3 2,当引用变量指向内存空间时,这个对象不为null,但是还没初始化,其他线程在调用getInstance方法使用时,会判断instance不为null,导致错误使用,出现异常

饿汉式

在类加载阶段就创建实例了

public class EagerSingleton {
    private final static EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {}

    public static EagerSingleton getInstance() {
        return instance;
    }
}
  • 线程安全,没加锁,效率高
  • 缺点是类加载就初始化,浪费内存空间

有关创建型设计模式的内容就更新到这了,下一篇更新结构型设计模式的内容


http://www.kler.cn/a/550845.html

相关文章:

  • Docker 容器日志与监控
  • 【对比】Pandas 和 Polars 的区别
  • Unity截取RenderTexture某帧画面显示在Image上
  • Leetcode 算法题 88. 合并两个有序数组
  • 802.3 两种格式
  • Redis 10章——集群(cluster)
  • 服务器A到服务器B免密登录
  • 【拒绝算法PUA】LeetCode 1287. 有序数组中出现次数超过25%的元素
  • maven使用默认settings.xml配置时,Idea基于pom.xml更新依赖时报错,有些组件下载时连接超时
  • 解锁JavaScript新姿势:Set数据结构深度解析
  • Unity Shader示例 6: 卡渲基础 - 描边 + 着色
  • 【学术投稿-第四届智能电网和绿色能源国际学术会议(ICSGGE 2025)】CSS基本选择器详解:掌握基础,轻松布局网页
  • 深入剖析 Python 爬虫:淘宝商品详情数据抓取
  • 什么是RDD以及它在Spark中的作用
  • 地基Spring中bean生命周期和设计模式
  • 为AI聊天工具添加一个知识系统 之108 详细设计之49 相提并论的三者、三位一体Triad和圣灵倒三角
  • Java爬虫获取1688商品搜索API接口的实现指南
  • 案例-05.部门管理-新增
  • 【Prometheus】prometheus结合domain_exporter实现域名监控
  • Qt——静态函数中发送信号方法总结(不需要通过类内部信号与槽实现,关键是清楚你发送的信号源自哪个对象)