常用设计模式1:单例模式(Java)

Java 中的单例模式

1. 什么是单例模式?

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在 Java 中,单例模式是最简单的设计模式之一,但其实现方式多样,每种方式都有其特点和适用场景。

2. 为什么使用单例模式?

  • 保证一个类只有一个实例
  • 提供对该实例的全局访问点
  • 控制共享资源的并发访问
  • 节省系统资源

3. Java 中实现单例模式的几种方式

3.1 懒汉式(线程不安全)

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

这种方式是最基本的实现方式,但它不是线程安全的。

3.2 懒汉式(线程安全)

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

这种方式通过同步方法确保了线程安全,但效率较低。

3.3 饿汉式

public class Singleton {
    private static final Singleton instance = new Singleton();
    private Singleton() {}
    
    public static Singleton getInstance() {
        return instance;
    }
}

饿汉式在类加载时就创建实例,天生线程安全,但不能实现延迟加载。

3.4 双重检查锁定

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

这种方式既实现了延迟加载,又保证了线程安全。

3.5 静态内部类

public class Singleton {
    private Singleton() {}
    
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

这种方式利用了类加载机制来保证初始化实例时只有一个线程。

3.6 枚举

public enum Singleton {
    INSTANCE;
    
    public void doSomething() {
        // 方法实现
    }
}

枚举实现是最简洁的方式,自动支持序列化机制,防止反序列化重新创建新的对象。

4. 单例模式的注意事项

  • 构造函数必须是私有的,防止外部直接实例化
  • 考虑对象序列化可能破坏单例模式
  • 多线程环境下需要特别注意线程安全问题
  • 注意延迟加载与性能之间的权衡

5. 单例模式的应用场景

  • 管理共享资源,如线程池、缓存、对话框、打印机等
  • 控制数据库连接,保证连接池的数量
  • 程序的日志应用,一般都使用单例模式实现日志对象
  • 配置文件的读取,一般也用单例模式实现

6. 总结

单例模式虽然简单,但在实际应用中需要根据具体情况选择合适的实现方式。在 Java 中,静态内部类和枚举方式是较为推荐的实现方式,它们能够保证线程安全,还能防止反序列化重新创建新的对象。

posted @ 2024-07-27 15:14  KenWan  阅读(50)  评论(0)    收藏  举报