Singleton设计模式中的同步(MyClass.class){} - 它做什么?

时间:2017-05-11 04:06:08

标签: java multithreading design-patterns syntax synchronized

我学习设计模式并拥有Java的中级经验。我试图实现Singleton设计模式,并在方法中遇到以下代码:

    public static Singleton getInstance(){

    if( firstInstance == null ){
        if (firstThread){
            firstThread = false;
            Thread.currentThread();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(Singleton.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        synchronized(Singleton.class){

            if(firstInstance == null){
                firstInstance = new Singleton();
            }

        }


    }

    return firstInstance;
}

我理解该方法的工作原理,但我对此代码的一个特定部分提出了疑问:

        synchronized(Singleton.class){

            if(firstInstance == null){
                firstInstance = new Singleton();
            }
        }

我知道synchronized块只强制同步这部分代码,这使得实现线程安全并且不会减慢整个方法的速度,但为什么要包装 {{1}访问修饰符 Singleton.class 之前的括号中的

我的问题与Java相关,而不是与设计模式相关。我尝试搜索Google和StackOverflow,但我不确定这实际上是什么,这限制了我的结果。

我希望你们能在这里帮助我。

提前致谢!

2 个答案:

答案 0 :(得分:1)

因为在Java中同步的正常事情是this(例如当前实例)。但是这个方法是static,所以没有实例,只有一个类。因此,我们同步。

synchronizing这部分方法的原因是两个实例不是一次创建两个实例。如果两者同时进行firstInstance == null检查,并且两者都发现true,则两者都决定创建新实例。这给了我们两个Singleton类的实例,这显然非常糟糕。

此外,当您致电synchronizedaccess modifier时,我认为您感到困惑。

唯一的访问修饰符是privatepublicprotected(加上隐藏的默认修饰符)。

Synchronizednon-access modifier。单个方法可以同时具有访问和非访问修饰符,例如public staticprivate synchronized

请注意,只有synchronizedstatic可以包含块。然而,这更多是因为它们的用途而不是它们的修饰语分类。

答案 1 :(得分:1)

firstInstance变量很可能是Singleton类中的静态变量,包含该类的唯一对象。

在类上进行同步可确保两个不同的线程不会同时尝试创建firstInstance对象。这可确保firstInstance变量仅初始化一次。