Java单例模式的七种实现方式

1. 饿汉式(静态常量)

  • 代码示例:
    public class Singleton {
        private static final Singleton INSTANCE = new Singleton();
        private Singleton() {}
        public static Singleton getInstance() { return INSTANCE; }
    }
    
  • 特点:
    • 线程安全:类加载时自动初始化,无需同步。
    • 非懒加载:可能造成资源浪费(若实例未被使用)。
  • 适用场景:资源占用小且频繁使用的单例。

2. 饿汉式(静态代码块)

  • 代码示例:
    public class Singleton {
        private static Singleton singleton;
        static { singleton = new Singleton(); }
        private Singleton() {}
        public static Singleton getInstance() { return singleton; }
    }
    
  • 特点:
    • 与静态常量实现类似,但代码结构更灵活(如初始化复杂逻辑)。
    • 缺点:同样存在非懒加载问题。

3. 懒汉式(非线程安全)

  • 代码示例:
    public class Singleton {
        private static Singleton instance;
        public static Singleton getInstance() {
            if (instance == null) instance = new Singleton();
            return instance;
        }
    }
    
  • 特点:
    • 延迟加载:首次调用时创建实例。
    • 线程不安全:多线程环境下可能生成多个实例。

4. 懒汉式(同步代码块/方法)

  • 代码示例:
    public class Singleton {
        private static Singleton instance;
        public static synchronized Singleton getInstance() {
            if (instance == null) instance = new Singleton();
            return instance;
        }
    }
    
  • 特点:
    • 线程安全:通过synchronized保证单例性。
    • 性能问题:每次调用均加锁,效率较低。

5. 双重检查锁定(DCL)

  • 代码示例:
    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;
        }
    }
    
  • 关键点:
    • volatile防止指令重排序,确保实例化过程可见性。
    • 线程安全且高效:仅首次调用加锁。

6. 静态内部类

  • 代码示例:
    public class Singleton {
        private Singleton() {}
        private static class SingletonHolder {
            private static final Singleton INSTANCE = new Singleton();
        }
        public static Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
    }
    
  • 特点:
    • 延迟加载:首次调用getInstance()时加载内部类。
    • 线程安全:JVM保证内部类初始化的原子性。

7. 枚举

  • 代码示例:
    public enum Singleton {
        INSTANCE;
        // 其他方法...
    }
    
  • 特点:
    • 天然线程安全:JVM确保枚举实例唯一性。
    • 防反射与序列化破坏:无法通过反射或反序列化创建新实例。
    • 不支持延迟加载。

总结与最佳实践

  1. 推荐实现:
    • 枚举:最简洁、安全,适合大多数场景。
    • 静态内部类:延迟加载且线程安全,兼容旧JDK。
  2. 避免使用:
    • 非线程安全的懒汉式(多线程环境)。
    • 同步方法/代码块(性能敏感场景)。
  3. 扩展场景:
    • ThreadLocal:需每个线程独立实例时使用。
    • 容器式单例:管理多个单例对象时适用。
      通过合理选择实现方式,可平衡性能、线程安全与代码简洁性。

你可能感兴趣的:(#,Java知识点,设计模式,java,单例模式,学习,笔记)