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

单例模式几种实现

静态内部类holder实现(推荐)

public class UniqueIdGenerator {
    public static final UniqueIdGenerator INSTANCE = Holder.INSTANCE;

    // Private holder class for lazy initialization
    private static class Holder {
        static final UniqueIdGenerator INSTANCE = new UniqueIdGenerator();
    }
    // Private constructor to prevent instantiation
    private UniqueIdGenerator() {
        // No need for reflection protection here since we're using holder pattern
    }
}

好处:懒加载,真正使用时才加载在,不占用内存。代码简洁性相对双重检查锁高。

双重检查锁实现

public class UniqueIdGenerator {
    // 使用 volatile 关键字保证可见性和禁止指令重排序
    private static volatile UniqueIdGenerator INSTANCE;

    // 私有构造函数,防止外部实例化
    private UniqueIdGenerator()

    // 公共静态方法,用于获取单例实例
    public static UniqueIdGenerator getInstance() {
        // 第一次检查,避免不必要的同步
        if (INSTANCE == null) {
            // 同步代码块,确保只有一个线程能进入创建实例
            synchronized (UniqueIdGenerator.class) {
                // 第二次检查,防止多个线程同时通过第一次检查后重复创建实例
                if (INSTANCE == null) {
                    INSTANCE = new UniqueIdGenerator();
                }
            }
        }
        return INSTANCE;
    }
}

经典单例模式(不推荐)

饿汉式(线程安全)

public class UniqueIdGenerator {
    // 在类加载时就创建单例实例
    private static final UniqueIdGenerator INSTANCE = new UniqueIdGenerator();

    // 私有构造函数,防止外部实例化
    private UniqueIdGenerator() {
        // 可以在这里添加初始化逻辑
    }

    // 公共静态方法,用于获取单例实例
    public static UniqueIdGenerator getInstance() {
        return INSTANCE;
    }
}

懒汉式单例模式(线程不安全)

public class UniqueIdGenerator {
    // 单例实例
    private static UniqueIdGenerator INSTANCE;

    // 私有构造函数,防止外部实例化
    private UniqueIdGenerator() {
        // 可以在这里添加初始化逻辑
    }

    // 公共静态方法,用于获取单例实例
    public static UniqueIdGenerator getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new UniqueIdGenerator();
        }
        return INSTANCE;
    }
}

更多可以参考下面,讲的很全。
https://zhuanlan.zhihu.com/p/93255556


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

相关文章:

  • Qt通过FFmpeg打开RTSP并截图一帧作为背景
  • Jenkins数据备份到windows FTP服务器
  • 【Java基础】为什么不支持多重继承?方法重载和方法重写之间区别、Exception 和 Error 区别?
  • DeepSeek-R1 32B Windows+docker本地部署
  • FaceFusion如何设置公开链接和端口
  • DeepSeek 评价开源框架存在幻觉么?
  • 【漫话机器学习系列】082.岭回归(或脊回归)中的α值(alpha in ridge regression)
  • Linux 安装 Ollama
  • ASP.NET Core WebSocket、SignalR
  • 从零开始掌握Python人工智能:实战案例、学习路径与职业建议
  • MOSSE目标跟踪算法详解
  • 深度学习-可调整嵌入维度、隐藏层维度和训练轮数
  • Chrome 浏览器 支持多账号登录和管理的浏览器容器解决方案
  • 二级C语言题解:迭代求根、字符串加法、字符串拆分
  • ARM Cortex-M3/M4 权威指南 笔记【一】架构
  • PHP 完整表单实例
  • 嵌入式硬件篇---OpenMV串口流和缓冲区
  • 用AI写游戏3——模拟发牌
  • Golang中 var make new
  • vue表格拖拽,可以多个单元格拖拽
  • html 列动态布局
  • 2025年2月份的一次前端面试题记录....
  • 使用Redis解决使用Session登录带来的共享问题
  • 深度学习-利用Tacotron 2 和 WaveGlow 模型 进行语音合成
  • Vue引入外部异步js函数并接收返回值
  • mysql中主键索引和联合索引的原理解析