单例模式(Singleton Pattern)是设计模式中的一种,它确保一个类只有一个实例,并提供一个全局访问点。这种模式在软件工程中被广泛使用,特别是在那些需要确保只有一个对象存在,或者需要节省资源的情况下。本文将详细介绍单例模式的功能分类及其实战解析。
单例模式的功能分类
1. 资源控制
单例模式常用于控制对某种资源的访问。例如,数据库连接池、文件操作对象等,由于资源有限,确保只有一个实例可以减少资源的浪费。
2. 避免全局变量
在面向对象编程中,全局变量通常是不推荐的。单例模式可以提供一个类似全局变量的功能,同时又保持了封装性。
3. 系统环境配置
系统级别的配置信息,如系统参数、配置文件等,可以使用单例模式来管理,以确保全局配置的一致性。
4. 缓存实现
单例模式适用于实现缓存机制,如LRU(最近最少使用)缓存,确保整个应用程序只有一个缓存实例。
单例模式的实现方式
1. 饿汉式单例
饿汉式单例是在类加载时就完成实例化,保证只有一个实例存在。这种方式简单,但是会占用一定的内存资源。
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
2. 懒汉式单例
懒汉式单例是在真正需要使用时才进行实例化。这种方式可以节省内存资源,但是可能会引起线程安全问题。
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
3. 双重校验锁单例
双重校验锁单例结合了懒汉式和同步方法的优势,解决了线程安全问题。
public class DoubleCheckedLockingSingleton {
private static volatile DoubleCheckedLockingSingleton instance;
private DoubleCheckedLockingSingleton() {}
public static DoubleCheckedLockingSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedLockingSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}
}
return instance;
}
}
4. 静态内部类单例
静态内部类单例利用了类加载机制保证了单例的唯一性,并且避免了同步带来的性能损耗。
public class StaticInnerClassSingleton {
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}
private StaticInnerClassSingleton() {}
public static final StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
单例模式的实战解析
以下是一个使用单例模式实现的数据库连接池的例子:
public class DatabaseConnectionPool {
private static DatabaseConnectionPool instance;
private static List<Connection> connections;
private DatabaseConnectionPool() {
connections = new ArrayList<>();
for (int i = 0; i < 10; i++) {
connections.add(createConnection());
}
}
private Connection createConnection() {
// 创建数据库连接
return DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "username", "password");
}
public static DatabaseConnectionPool getInstance() {
if (instance == null) {
synchronized (DatabaseConnectionPool.class) {
if (instance == null) {
instance = new DatabaseConnectionPool();
}
}
}
return instance;
}
public Connection getConnection() {
// 从连接池中获取连接
return connections.get(0);
}
}
在这个例子中,DatabaseConnectionPool 类负责管理数据库连接。它使用双重校验锁单例模式确保只有一个实例,并且提供了连接池的功能。
总结,单例模式是一种简单而强大的设计模式,可以用于控制资源访问、避免全局变量、管理系统配置和实现缓存等功能。在实战中,应根据具体需求选择合适的单例模式实现方式。
