Singleton Pattern(Java)中的同步块

问题描述 投票:1回答:2

我对我在Wikipedia上发现的线程安全Singleton模式有疑问。

public final class Singleton {

    private static volatile Singleton instance = null;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}

如果已同步的块未同步,那么两个线程可以同时创建两个对象吗?

我需要说明作业的“同步”用法。

感谢和问候

java multithreading synchronized volatile
2个回答
0
投票

如果未同步,则确实可以有2个线程创建2个对象。

  • T1:检查实例是否为空=>是! =>继续下一行
  • T2:检查实例是否为空=>是! =>继续下一行
  • T1:创建对象
  • T2:创建对象

使用同步时,一次只能有1个线程进入同步阻止状态。

  • T1:检查实例是否为空=>是! =>继续下一行
  • T1:创建对象
  • T2:检查实例是否为空=>否! =>跳过块

编辑:

值得注意的是,已同步内部的空检查封锁实际上非常重要-否则有可能同时创建2个对象。 –当中(评论中)

以下是实现单例模式的另一种方法。 仅在应用程序启动后创建对象不是大问题时才使用此模式:

public final class Singleton {

    private static Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

-2
投票

您写的被称为Draconian同步。这意味着,为了使上述模式适应多线程环境,您需要确保在给定时间只有一个线程可以执行getInstance()方法。因此,是的,最简单的方法是对该方法使用synced关键字。

© www.soinside.com 2019 - 2024. All rights reserved.