单例模式的几种实现方式

单例模式(Singleton Pattern)是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点。这种模式在需要全局状态或者希望整个应用程序中某个对象只有一个实例时非常有用。

单例模式的关键特点包括:

  1. 唯一实例:单例类通过私有构造函数和静态实例变量确保只有一个实例被创建。
  2. 全局访问点:单例类提供一个公共的静态方法,允许其他对象获取到这个唯一实例的引用。
  3. 延迟初始化:单例实例可以在第一次使用时创建,也可以在类加载时立即创建。延迟初始化有助于节省资源,因为它允许系统在需要时才创建实例。
  4. 线程安全:在多线程环境中,单例模式需要确保线程安全,避免多个线程同时创建多个实例。

实现方案的话,我这里推荐三种:

1、枚举(推荐)

java 复制代码
public enum Singleton {
    INSTANCE;
    public void doSomething(String str) {
        System.out.println(str);
   }
}

《Effective Java》作者推荐的⼀种单例实现⽅式,简单⾼效,⽆需加锁,线程安全,可以避免通过 反射破坏枚举单例。

2、静态内部类(推荐)

java 复制代码
public class Singleton {
    // 私有化构造⽅法
    private Singleton() {
   }
    // 对外提供获取实例的公共⽅法
    public static Singleton getInstance() {
        return SingletonInner.INSTANCE;
   }
    // 定义静态内部类
    private static class SingletonInner{
        private final static Singleton INSTANCE = new Singleton();
   }
}

当外部类Singleton被加载的时候,并不会创建静态内部类SingletonInner的实例对象。只有当调 ⽤getInstance()⽅法时, SingletonInner才会被加载,这个时候才会创建单例对象INSTANCE 。 INSTANCE的唯⼀性、创建过程的线程安全性,都由 JVM 来保证。 这种⽅式同样简单⾼效,⽆需加锁,线程安全,并且⽀持延时加载。

3、双重校验锁

java 复制代码
public class Singleton {
    private volatile static Singleton uniqueInstance;
    // 私有化构造⽅法
    private Singleton() {
   }
    public  static Singleton getUniqueInstance() {
       //先判断对象是否已经实例过,没有实例化过才进⼊加锁代码
        if (uniqueInstance == null) {
            //类对象加锁
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
               }
           }
       }
        return uniqueInstance;
   }
}

uniqueInstance采⽤volatile关键字修饰也是很有必要的,uniqueInstance = new Singleton();这段 代码其实是分为三步执⾏: 1. 为uniqueInstance分配内存空间 2. 初始化uniqueInstance 3. 将uniqueInstance指向分配的内存地址 但是由于 JVM 具有指令重排的特性,执⾏顺序有可能变成 1->3->2。指令重排在单线程环境下不会 出现问题,但是在多线程环境下会导致⼀个线程获得还没有初始化的实例。例如,线程 T1 执⾏了 1 和 3,此时 T2 调⽤getUniqueInstance () 后发现uniqueInstance不为空,因此返回uniqueInstance ,但此时uniqueInstance还未被初始化。

这种⽅式实现起来较麻烦,但同样线程安全,⽀持延时加载。

相关推荐
子非鱼a17 分钟前
【WEB】[SWPU2019]Web1
java·服务器·前端
花生了什么事o22 分钟前
自定义Spring Boot Starter全流程
java·spring boot·后端
torpidcat1 小时前
ruoyi-vue-pro 若依芋道 java springboot +mybatis 生日查询相关
java·vue.js·spring boot
AC赳赳老秦2 小时前
文旅市场公开数据分析:基于 OpenClaw 采集景区客流与门票公示数据,生成区域文旅热度监测报告
java·c语言·python·php·symfony·deepseek·openclaw
我命由我123452 小时前
Windows 操作系统 - 启用 D 盘虚拟内存
java·运维·服务器·windows·学习·java-ee·运维开发
xcl09253 小时前
智慧场馆解决方案系统源码:从架构设计到部署实战
java·spring boot
liangbo73 小时前
06-JVM垃圾回收器之CMS
java·jvm
黑马程序员毕设3 小时前
基于Java的仪器管理系统设计与实现
java·开发语言·spring boot·后端·微信小程序
骇客野人3 小时前
SpringBoot电商购物车、结算、下单、库存方案设计与落地实施步骤
java·spring boot·后端
哪 吒3 小时前
华为OD机试 - 云服务安全策略最优选择 - 深度优先搜索DFS(Java 新系统 200分)
java·华为od·深度优先