单例模式(Singleton Pattern)属于创建型模式,它确保在同一个进程内,单例类只有一个对象,并且 该对象对所有其他对象提供访问,常见的如Windows系统下的资源管理器、Spring Bean等都会采用这种方式。
一般来说,正确实现单例有如下几点要求:
将其构造方法设为私有;
防止对象在初始化被多个线程同时运行;
确保该对象不可序列化;
确保该对象无法克隆。
下面举例介绍实现单例模式的四种方法:
一、利用枚举实现单例:
利用枚举实现单例时,枚举类的静态成员变量的初始化在构造方法之后执行,构造方法中不要操 作静态成员变量。
enum RecommandSingleton {
SINGLETON;
public void doSomething() {
}
}
二、利用静态内部类实现单例:
final class RecommandSingleton {
private static class SingletonHolder {
static final RecommandSingleton INSTANCE = new RecommandSingleton();
}
private RecommandSingleton() {
}
public static RecommandSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
三、利用Spring的依赖注入能力实现单例(其他诸如Guice、Dagger等也可以实现):
@Component
class RecommandSingleton {
public void doSomething() {
}
}
@Component
class SomeServiceImpl {
private final RecommandSingleton singleton;
@Autowired
public SomeServiceImpl(RecommandSingleton singleton) {
this.singleton = singleton;
}
}
四、双重检查锁
把 instance 声明为 volatile ,当一个线程初始化 Singleton 对象时,会在这个线程和 其他任何获取该实例的线程之间建立起happens-before关系。避免使用到未初始化完全的对象引用。
final class Singleton {
private static volatile Singleton instance = null;
private static final Object LOCK = new Object();
private Singleton() {
...
}
public static Singleton getSingletonInstance() {
if (instance == null) {
synchronized (LOCK) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}