- 延迟初始化
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 static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
通过提前初始化,避免每次在调用getInstance 方法产生的同步开销。
- 延长初始化占位模式
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
提前初始化的方式和JVM延迟加载机制结合前来,形成的延迟初始化技术,在常见的代码路径中不需要同步。代码中使用一个专门的类初始单例对象,JVM将延迟内部类SingletonHolder得初始化操作,直到开始使用这个类才初始化,并且由于通过一个静态初始化来初始化INSTANCE,,因此不需要额外的同步。当任何一个线程首次调用getInstance,都会使 Resource被加载而初始化INSTANCE。
----------
Double check
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
“`
这种方式十分常见,仅在jdk5.0以上的版本支持,需要吧instance声明为 volatile类型,这种方式对性能影响很小,volatile变量读取操作得性能略低于非volatile变量。然而这种方式在现代JVM中不建议使用,推荐使用性能同样出色的延长初始化占位模式,而且容易理解。