Initialization-on-demand holder Idiom 能否导致部分创建的对象?

Can Initialization-on-demand holder Idiom result in a partially created object?

 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 变量?

来自 Wikipedia 关于按需初始化持有人习语的文章:

Since the class initialization phase is guaranteed by the JLS to be serial, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization. And since the initialization phase writes the static variable INSTANCE in a serial operation, all subsequent concurrent invocations of the getInstance will return the same correctly initialized INSTANCE without incurring any additional synchronization overhead

答案是。这是因为语句“初始化阶段在串行操作中写入静态变量 INSTANCE”。也就是说,当一个线程调用 getInstance 时,另一个线程对 getinstance 的调用将等待 SingletonHolder 完全加载。要完全加载 SingletonHolder,必须创建 INSTANCE。一旦 SingletonHolder 被加载,任何对 getInstance 的后续调用将简单地 return INSTANCE 而没有 synchronization 开销。

加载类时使用的锁定机制在JLS的Section 12.4.2中有详细描述。