单例模式是Java设计模式中最经典和最常用的模式之一。它确保一个类只有一个实例,并提供一个全局访问点。本文将深入解析Java中常见的5种单例模式的创建方式,并通过实战应用来展示如何正确使用单例模式。
1. 懒汉式单例
懒汉式单例是指在类加载时不初始化,第一次使用时才创建实例。这种方式可以延迟单例的创建时间,减少资源消耗。
1.1 静态初始化器
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
1.2 双重校验锁
public class LazySingleton {
private static volatile LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
}
2. 饿汉式单例
饿汉式单例是在类加载时就初始化单例实例,保证类加载时就完成实例化。
2.1 静态常量
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
2.2 静态代码块
public class EagerSingleton {
private static EagerSingleton instance;
static {
instance = new EagerSingleton();
}
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
3. 静态内部类单例
静态内部类单例利用了类加载机制保证单例的唯一性。
3.1 静态内部类
public class StaticInnerClassSingleton {
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}
private StaticInnerClassSingleton() {}
public static final StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
4. 枚举单例
枚举单例是实现单例的最佳方式之一,它可以防止反射和反序列化破坏单例。
4.1 枚举实现
public enum EnumSingleton {
INSTANCE;
public void someMethod() {
// 实现业务逻辑
}
}
5. 实战应用
以下是一个使用单例模式实现数据库连接池的示例:
public class DatabaseConnectionPool {
private static final DatabaseConnectionPool instance = new DatabaseConnectionPool();
private List<Connection> connections;
private DatabaseConnectionPool() {
connections = new ArrayList<>();
// 初始化连接池
}
public static DatabaseConnectionPool getInstance() {
return instance;
}
public Connection getConnection() {
// 从连接池中获取连接
return connections.get(0);
}
}
通过以上5种单例模式的创建方式,我们可以根据实际需求选择合适的方法。在实际应用中,建议使用静态内部类单例或枚举单例,这两种方式简单且安全。
