Java单例模式详解
单例模式是设计模式中的一种,它确保某一个类只有一个实例,并提供一个全局点来访问这个实例。这在某些场景中是非常有用的,例如,配置管理、线程池、缓存、日志对象等。
1. 单例模式的基本原则:
- 构造函数是私有的。
- 有一个私有静态变量来保存类的唯一实例。
- 有一个公有静态方法,供外界获取类的唯一实例。
2. 实现方法:
- 饿汉式:在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。
javaCopy code
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
- 懒汉式:在第一次调用时初始化并创建实例。需要注意线程安全。
javaCopy code
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
注意:上述方法使用了synchronized
关键字来确保线程安全,但这会使方法同步,可能会影响性能。
- 双重校验锁(Double-Checked Locking):结合了懒汉式和synchronized的优点,单例延迟初始化且线程安全,但需要注意
volatile
的使用。
javaCopy code
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 静态内部类:使用内部类的方式来实现单例,既保证了线程安全,又能够延迟加载。
javaCopy code
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 枚举方式:使用枚举来实现单例是推荐的方法,因为它既保证线程安全,又防止反序列化创建另一个实例。
javaCopy code
public enum Singleton {
INSTANCE;
public void someMethod() {
// some singleton behavior
}
}
3. 注意事项和陷阱:
- 防止反射攻击:即使构造函数是私有的,也可以通过反射来调用构造函数创建多个实例。
- 防止序列化创建多个实例:如果一个单例类实现了
Serializable
接口,那么它的序列化和反序列化可能会创建多个实例。可以通过提供readResolve
方法来解决这个问题。
结论:
单例模式是一个非常有用的设计模式,但实现它需要注意多线程安全、反射、序列化等问题。在Java中,使用枚举实现单例是最简单、安全的方法。但无论选择哪种方法,都要确保满足单例的基本原则和要求。
标签:Singleton,Java,private,instance,详解,static,单例,public From: https://blog.51cto.com/u_16170893/7044356