【Java面试指北】单例模式

单线程下的单例模式:

java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

几个关键点:

  • static 修饰:表名属于类而不是类对象,不会每生成一个新的类对象都新生成一份。并且可以在不创建类对象的情况下直接调用。
  • 为什么构造函数是private 类型?不然呢,开放了构造函数还怎么单例。
  • 为什么不把单例的逻辑放到构造函数中?在 Singleton() 中调用 Singleton() 么,那不是死循环了。
  • 类中的单例变量是 private 类型的,不能直接访问,要通过 getInstance() 来获取。

多线程下的单例模式:

和单线程有什么区别?

  • 需要考虑线程安全问题
  • 需要考虑效率问题

方法一:

只需要给 getInstance 方法添加 synchronized 关键字即可。

java 复制代码
public static synchronized Singleton getInstance() {

问题:每次访问都要同步,会降低性能。

方法二:

双重检查锁定

java 复制代码
public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton()
                }
            }
        }
        return instance;
    }
}

关键点:

  • 性能优化:将 synchronized 放到实际创建时,只有第一次实例未创建才会同步,后续都不会。
  • 为什么要双重检查 instance==null?第一次检查完,有可能被别的线程先创建了。
  • 为什么 instance 要用 volatile 修饰?
    • 因为 new Singleton() 不是一个单一的操作,会存在指令重排的问题。
    • 1、为 instance 分配内存空间。2、初始化 instance。3、将 instance 指向分配的内存地址。
    • 如果指令重拍后,变为了 1-3-2,那么其他线程可能会拿到一个还没初始化的 instance
  • 为什么有了 volatile 还需要 synchronized
    • 因为 volatile 不保证原子性。
相关推荐
惊涛骇浪、3 分钟前
SpringMVC + Tomcat10
java·tomcat·springmvc
墨染点香16 分钟前
LeetCode Hot100【6. Z 字形变换】
java·算法·leetcode
ldj202039 分钟前
SpringBoot为什么使用new RuntimeException() 来获取调用栈?
java·spring boot·后端
超龄超能程序猿40 分钟前
Spring 应用中 Swagger 2.0 迁移 OpenAPI 3.0 详解:配置、注解与实践
java·spring boot·后端·spring·spring cloud
风象南1 小时前
SpringBoot配置属性热更新的轻量级实现
java·spring boot·后端
洛阳泰山1 小时前
Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解
java·spring boot·后端·nacos
Y4090011 小时前
C语言转Java语言,相同与相异之处
java·c语言·开发语言·笔记
YuTaoShao1 小时前
【LeetCode 热题 100】994. 腐烂的橘子——BFS
java·linux·算法·leetcode·宽度优先
布朗克1681 小时前
java常见的jvm内存分析工具
java·jvm·数据库
都叫我大帅哥2 小时前
深入浅出 Resilience4j:Java 微服务的“免疫系统”实战指南
java·spring cloud