单例模式
单例模式是一种常见的设计模式,它保证一个类只有一个实例,并提供一个全局访问点来获取该实例。以下是单例模式的一般实现方式:
饿汉式单例模式
public class Singleton {
private static Singleton instance = new Singleton(); // 在类加载时就创建实例
private Singleton() {} // 私有化构造方法
public static Singleton getInstance() {
return instance;
}
}
饿汉式单例模式在类加载时就创建了实例,因此线程安全,但可能造成资源浪费,如果实例不需要早期初始化或者创建过程比较耗时,可以考虑懒汉式单例模式。
懒汉式单例模式
public class Singleton {
private static Singleton instance;
private Singleton() {} // 私有化构造方法
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式单例模式在第一次调用getInstance()方法时才会创建实例,避免了资源浪费,但可能存在线程安全问题,可以通过加锁来解决。
双重检查锁定单例模式
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;
}
}
双重检查锁定单例模式通过使用volatile关键字和双重判空来保证线程安全,同时避免了不必要的加锁操作。
反射模式
反射是一种在运行时动态获取和操作类信息的机制,可以通过反射实现对类、属性、方法等的访问与操作。以下是使用反射创建单例模式的示例:
public class Singleton {
private static Singleton instance;
private Singleton() {
if (instance != null) {
throw new IllegalStateException("Already instantiated");
}
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
try {
Class<?> cls = Class.forName("com.example.Singleton");
Constructor<?> constructor = cls.getDeclaredConstructor();
constructor.setAccessible(true);
instance = (Singleton) constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return instance;
}
}
上述代码中,通过反射获取Singleton类的构造方法,并设置为可访问,然后使用反射创建实例。需要注意的是,在Singleton的私有构造方法中添加了实例已存在的判断,防止通过反射创建多个实例。
反射模式可以灵活地使用类的信息,但也增加了代码的复杂性和运行时的开销。在实际应用中,需要谨慎使用反射,避免不必要的性能损耗。