一旦像这样初始化,我可以避免双重检查锁定中的易失性读取吗?

S-C*_*S-C 2 java concurrency

通过使用只在实例为null时才读取的volatile布尔值,一旦实例初始化,我可以避免默认/频繁的volatile读取吗?没有看到有人建议双重检查锁定这样,但似乎避免挥发性读取一旦完全初始化...

public class Singleton {

   private static volatile boolean initialized = false;
   private static Object lock = new Object();
   private static Singleton instance;

      public static Singleton getInstance(){
           if(instance != null) return instance;
           if(!initialized){
                synchronized(lock){
                   if(!initialized){
                       instance = new Singleton();
                       initialized = true;
                   }
                }
           }
           return instance;

       }
Run Code Online (Sandbox Code Playgroud)

}

Mat*_*Mat 5

你不能.如果线程A已到达同步块并正在执行

instance = new Singleton();
Run Code Online (Sandbox Code Playgroud)

在线程中,进入函数的线程B可以instance在线程A完成构造对象之前看到初始化.因此,您有可能让线程B尝试处理部分构造的对象.

有关此模式的变体和说明,请参阅DLCP文章.