单例模式

定义

单例模式(Singleton Pattern)是java最简单的设计模式之一,用于保证某个类在运行期间只有一个实例对外提供服务,我们称这种类型的类为单例类。

设计原则

  1. 保证一个类只有一个实例;

  2. 为实例提供一个全局访问点。

实现方式

饿汉式

代码示例

java 复制代码
package com.sumlv.javase.note;

/**
 * 单例示例
 *
 * @Auther: yuzhuo.song
 * @Date: 2025-03-14
 */
public class Singleton {

    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }

    /**
     * 用于避免序列化对单例的破坏
     * 如果单例类没有实现序列化接口则不需要该方法
     * 
     * @return 实例对象
     */
    private Object readResolve() {
        return instance;
    }

    /**
     * 用于避免反射对单例的破坏
     */
    private Singleton() {
        if (instance != null) {
            throw new RuntimeException("illegal access");
        }
    }

}

补充说明

  1. 线程安全;

  2. 不支持延时加载;

  3. 获取实例对象速度较快;

  4. 如果实例对象较大且一直未使用会造成内存浪费。

懒汉式

代码示例

java 复制代码
package com.sumlv.javase.note;

/**
 * 单例示例
 *
 * @Auther: yuzhuo.song
 * @Date: 2025-03-14
 */
public class Singleton {

    private static Singleton instance;

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

        return instance;
    }

    /**
     * 用于避免序列化对单例的破坏
     * 如果单例类没有实现序列化接口则不需要该方法
     * 
     * @return 实例对象
     */
    private Object readResolve() {
        return instance;
    }

    /**
     * 用于避免反射对单例的破坏
     */
    private Singleton() {
        if (instance != null) {
            throw new RuntimeException("illegal access");
        }
    }

}

补充说明

  1. 支持延迟加载;

  2. 保证多线程模式下实例的唯一性;

  3. 并发度低,在频繁调用时会产生性能瓶颈。

双重检查锁

代码示例

java 复制代码
package com.sumlv.javase.note;

/**
 * 单例示例
 *
 * @Auther: yuzhuo.song
 * @Date: 2025-03-14
 */
public class Singleton {

    private static volatile Singleton instance;

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

        return instance;
    }

    /**
     * 用于避免序列化对单例的破坏
     * 如果单例类没有实现序列化接口则不需要该方法
     * 
     * @return 实例对象
     */
    private Object readResolve() {
        return instance;
    }

    /**
     * 用于避免反射对单例的破坏
     */
    private Singleton() {
        if (instance != null) {
            throw new RuntimeException("illegal access");
        }
    }

}

补充说明

  1. 支持延迟加载;

  2. 并发度高,在频繁调用时不会产生性能瓶颈。

静态内部类

代码示例

java 复制代码
package com.sumlv.javase.note;

/**
 * 单例示例
 *
 * @Auther: yuzhuo.song
 * @Date: 2025-03-14
 */
public class Singleton {

    public static Singleton getInstance() {
        return InnerClass.instance;
    }

    /**
     * 用于避免序列化对单例的破坏
     * 如果单例类没有实现序列化接口则不需要该方法
     * 
     * @return 实例对象
     */
    private Object readResolve() {
        return InnerClass.instance;
    }

    /**
     * 用于避免反射对单例的破坏
     */
    private Singleton() {
        if (InnerClass.instance != null) {
            throw new RuntimeException("illegal access");
        }
    }

    private static class InnerClass {

        private static Singleton instance = new Singleton();

    }

}

补充说明

  1. 支持延迟加载;

  2. 并发度高,在频繁调用时不会产生性能瓶颈。

  3. 实现方式相较于双重检查锁更为简洁。

枚举

代码示例

java 复制代码
package com.sumlv.javase.note;

/**
 * 单例示例
 *
 * @Auther: yuzhuo.song
 * @Date: 2025-03-14
 */
public enum Singleton {

    INSTANCE;

    public static Singleton getInstance() {
        return INSTANCE;
    }

}

补充说明

  1. 最简单的单例实现方式;

  2. 线程安全;

  3. 无需关心反射和序列化对单例造成破坏;

相关推荐
重生之我是Java开发战士1 天前
【Java SE】多线程(三):单例模式,阻塞队列,线程池与定时器
java·javascript·单例模式
许彰午3 天前
34_Java设计模式之单例模式
java·单例模式·设计模式
罗超驿4 天前
10.Java单例模式全解析:饿汉式与懒汉式实现及线程安全深度剖析
安全·单例模式·javaee
布朗克1684 天前
33 设计模式精讲
java·单例模式·设计模式
雨浓YN5 天前
基于设计模式的Winform软件框架-01Xml\Log\Ini日志(单例模式+生产者消费者模式)
单例模式·设计模式
仙俊红5 天前
Java 单例模式:类里面为什么可以有自己类型的字段?
java·开发语言·单例模式
swordbob6 天前
prototype 注入到 singleton 里,prototype是否还是线程安全的
安全·spring·单例模式·原型模式
谁似人间西林客7 天前
工业大数据实战:看中国智造如何用数据驱动效率革命
大数据·单例模式
张小姐的猫7 天前
【Linux】多线程 —— 线程池 | 单例模式 | 常见锁
linux·运维·服务器·c++·单例模式·设计模式·策略模式
Java面试题总结9 天前
双重检验锁的单例模式在高并发下的可见性问题
单例模式