Java单例模式案例如何实现

wen java案例 23

本文目录导读:

Java单例模式案例如何实现

  1. 饿汉式(线程安全)
  2. 懒汉式(线程不安全)
  3. 懒汉式(同步方法,性能较低)
  4. Double-Checked Locking(双重检查锁定)
  5. 静态内部类(推荐方式)
  6. 枚举方式(最安全的实现方式)
  7. 完整测试代码
  8. 防止反射和序列化攻击
  9. 总结与选择建议

我来详细介绍Java单例模式的几种经典实现方式。

饿汉式(线程安全)

/**
 * 饿汉式:类加载时就创建实例,线程安全
 */
public class Singleton {
    // 私有静态实例,类加载时创建
    private static final Singleton INSTANCE = new Singleton();
    // 私有构造方法
    private Singleton() {
        System.out.println("Singleton 实例已创建");
    }
    // 公共的获取实例方法
    public static Singleton getInstance() {
        return INSTANCE;
    }
    // 业务方法示例
    public void doSomething() {
        System.out.println("执行业务逻辑");
    }
}

懒汉式(线程不安全)

/**
 * 懒汉式:第一次调用时创建实例,线程不安全
 */
public class Singleton {
    private static Singleton instance;
    private Singleton() {
        System.out.println("Singleton 实例已创建");
    }
    public static Singleton getInstance() {
        if (instance == null) {  // 线程不安全
            instance = new Singleton();
        }
        return instance;
    }
}

懒汉式(同步方法,性能较低)

/**
 * 懒汉式:使用synchronized同步方法,线程安全但性能低
 */
public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    // 同步整个方法,每次获取实例都需要获取锁
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

Double-Checked Locking(双重检查锁定)

/**
 * 双重检查锁定:推荐使用,线程安全且性能较好
 */
public class Singleton {
    // volatile关键字保证可见性和禁止指令重排序
    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;
    }
}

静态内部类(推荐方式)

/**
 * 静态内部类:线程安全,延迟加载,推荐使用
 */
public class Singleton {
    // 私有构造方法
    private Singleton() {}
    // 静态内部类,只有在第一次使用时才会加载
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    // 获取实例方法
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
    // 业务方法
    public void doSomething() {
        System.out.println("使用单例对象执行业务");
    }
}

枚举方式(最安全的实现方式)

/**
 * 枚举单例:天然线程安全,防止反射攻击和序列化问题
 */
public enum Singleton {
    INSTANCE;  // 唯一的实例
    // 可以添加其他字段和方法
    private String config;
    // 枚举构造函数
    Singleton() {
        this.config = "默认配置";
        System.out.println("枚举单例初始化");
    }
    // 业务方法
    public void doSomething() {
        System.out.println("使用枚举单例:" + config);
    }
    // getter/setter
    public String getConfig() {
        return config;
    }
    public void setConfig(String config) {
        this.config = config;
    }
}

完整测试代码

public class SingletonTest {
    public static void main(String[] args) {
        // 测试饿汉式
        System.out.println("=== 饿汉式测试 ===");
        Singleton.instance.doSomething();
        // 测试静态内部类
        System.out.println("\n=== 静态内部类测试 ===");
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println("是否是同一个实例:" + (instance1 == instance2));
        // 测试枚举单例
        System.out.println("\n=== 枚举单例测试 ===");
        SingletonEnum.INSTANCE.doSomething();
        SingletonEnum.INSTANCE.setConfig("自定义配置");
        SingletonEnum.INSTANCE.doSomething();
        // 多线程测试
        System.out.println("\n=== 多线程测试 ===");
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                Singleton singleton = Singleton.getInstance();
                System.out.println(Thread.currentThread().getName() + ": " + singleton);
            }).start();
        }
    }
}

防止反射和序列化攻击

import java.io.Serializable;
/**
 * 安全的单例:防止反射和序列化破坏
 */
public class SafeSingleton implements Serializable {
    private static final long serialVersionUID = 1L;
    private static volatile SafeSingleton instance;
    private SafeSingleton() {
        // 防止反射创建实例
        if (instance != null) {
            throw new RuntimeException("不允许创建多个实例!");
        }
    }
    public static SafeSingleton getInstance() {
        if (instance == null) {
            synchronized (SafeSingleton.class) {
                if (instance == null) {
                    instance = new SafeSingleton();
                }
            }
        }
        return instance;
    }
    // 防止序列化破坏单例
    private Object readResolve() {
        return getInstance();
    }
}

总结与选择建议

实现方式 线程安全 延迟加载 推荐度 适用场景
饿汉式 简单场景,实例不复杂
懒汉式(同步) 不推荐,性能差
双重检查锁定 高性能需求
静态内部类 推荐,简洁高效
枚举 最推荐,安全可靠

推荐使用

  • 一般场景:静态内部类双重检查锁定
  • 需要最佳安全性:枚举方式
  • 简单场景:饿汉式

抱歉,评论功能暂时关闭!