class SingletonImpl{
private SingletonImpl() {
/*
* time consuming operation
*/
}
private static class SingletonHolder {
private static final SingletonImpl INSTANCCE = new SingletonImpl();
}
public static SingletonImpl getInstance(){
return SingletonHolder.INSTANCCE;
}
}
我们是否有可能将半熟(未完全初始化)对象转换为INSTANCE变量?
答案 0 :(得分:4)
来自Wikipedia关于Intitialization-on-demand holder惯用语的文章:
由于JLS保证类初始化阶段是串行的,即非并发的,因此在加载和初始化期间静态getInstance方法不需要进一步的同步。由于初始化阶段将静态变量INSTANCE写入串行操作,因此getInstance的所有后续并发调用将返回相同的正确初始化INSTANCE,而不会产生任何额外的同步开销
答案是否。这是因为语句“初始化阶段将静态变量INSTANCE写入串行操作”。也就是说,当一个线程调用getInstance
时,从另一个线程调用getinstance
将等到SingletonHolder
完全加载。要使SingletonHolder
完全加载,必须创建INSTANCE
。加载SingletonHolder
后,对getInstance
的任何后续调用都只会返回INSTANCE
而没有synchronization
开销。
在加载类时使用的锁定机制在JLS的Section 12.4.2中有详细描述。