
在 Java 中,实现单例模式的常用方式包括:
饿汉式(Eager Initialization):在类加载时就创建实例,并在静态成员变量中持有该实例。这种方式简单直接,但如果实例不被使用,会造成资源浪费。
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}懒汉式(Lazy Initialization):在首次访问时才创建实例。这种方式延迟了实例的创建,但需要考虑线程安全性。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}双重检查锁(Double-Checked Locking):结合了饿汉式和懒汉式的优点,在首次访问时延迟创建实例,并使用双重检查锁机制确保线程安全。
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;
}
}静态内部类(Static Inner Class):利用类加载机制保证线程安全,且实现简单优雅。当 Singleton 类加载时,静态内部类 SingletonHolder 不会被加载,只有在调用 getInstance() 方法时才会加载 SingletonHolder 类,从而实现懒加载。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}单例模式适用于以下场景:
在使用单例模式时需要注意以下几点:
Serializable 接口,并且重写 readResolve() 方法,确保反序列化时返回同一个实例。
单例模式是一种常见的设计模式,它可以确保一个类只有一个实例,并提供一个全局访问点来访问该实例。在实际应用中,可以根据具体场景选择不同的实现方式,并注意线程安全性、序列化和反序列化、类加载器等问题。合理使用单例模式可以提高代码的可维护性和性能,并且降低资源消耗。