1. 兼顾效率与并发安全的懒汉单例模式
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;
}
双重校验锁的实现方式中,静态成员变量singleton必须通过volatile来修饰,保证其初始化的原子性,否则可能被引用到一个未初始化完成的对象。
2. 饿汉单例模式
如果已知某一个对象一定会使用到的话,其实可以采用一种饿汉的实现方式。
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return singleton;
}
}
因为类的初始化是由ClassLoader完成的,这其实是利用了ClassLoader的线程安全机制。ClassLoader的loadClass方法在加载类的时候使用了synchronized关键字。也正是因为这样, 除非被重写,这个方法默认在整个装载过程中都是线程安全的
3. 静态内部类实现单例
public class Singleton {
private Singleton() {}
private static class SingletionInner {
private static final Singleton SINGLETON = new Singleton();
}
public static final Singleton getInstance() {
return SingletionInner.SINGLETON;
}
}
使用静态内部类,借助了classloader来实现了线程安全,这与饿汉模式有着异曲同工之妙,但是他有兼顾了懒汉模式的lazy-loading功能