以下Singleton在多线程环境中是否不安全

时间:2014-09-01 16:40:57

标签: java multithreading synchronization singleton

我想确保我的Singleton实例安全可用且同步最少,但我对同步块之外的第一个if子句有疑问。 INSTANCE是否有可能在未完全构造时具有非空值?如果是这样,我该如何解决这个问题。

我认为包含整个get()块会降低效率,因为会有很多配置变量必须通过此get()方法从程序的不同部分每秒读取数千次。

public class ConfsDBLoader {

    private static ConfsDBLoader INSTANCE = null;
    private static final Object lock = new Object();

    private ConfsDBLoader() { //Codes loading the db objects
    }

    public static ConfsDBLoader get(){
        if(INSTANCE != null){
            return INSTANCE;
        } else {
            synchronized(lock){
                if(INSTANCE == null){
                    INSTANCE = new ConfsDBLoader();
                }
                return INSTANCE;
            }
        }
    }

}

注意:我不能使用静态初始化,因为我的hibernate sessionFactory是静态初始化的,我想拥有彼此需要的复杂静态结构。事实上,我已经拥有它,我不想让它变得越来越复杂,并研究这些静态属性试图相互使用的位置。

1 个答案:

答案 0 :(得分:2)

没有。没有足够的同步来确保您在INSTANCE上看到正确的值。如果你的ConfsDBLoader,你可能会看到一个非null但是损坏的实例,因为在另一个线程调用getInstance()时它可能没有正确构造。

您有3个选择:

  • 渴望初始化并做出最终决定
  • 同步整个方法
  • 制作实例volatile