1

关于我之前提出的一个问题,

    public static Singleton getInstanceDC() {
    if (_instance == null) {                // Single Checked (1)
        synchronized (Singleton.class) {
            if (_instance == null) {        // Double checked (2)
                _instance = new Singleton();
            }
        }
    }
    return _instance;

}

为什么要使用第二个实例空检查条件。它可能产生什么影响?

4

1 回答 1

4

让我们给行编号,这样我们就可以看到线程如何交错操作。

if (_instance == null) {                // L1
    synchronized (Singleton.class) {    // L2
        if (_instance == null) {        // L3
            _instance = new Singleton();// L4
        }
    }
}

让我们考虑一个不检查 L3 的交错。

  1. 线程 1 到达 L1 并且_instancenull
  2. 线程 2 到达 L1 并且_instancenull
  3. 线程 1 在 L2 获得互斥量
  4. 线程 2 尝试在 L2 获取互斥体但阻塞
  5. 线程 1 创建新实例并在 L4 分配
  6. 线程 1 从 L2 释放互斥锁
  7. 线程 2 在 L2 获得互斥量
  8. 线程 2 创建新实例并在 L4 分配
  9. 线程 2 从 L2 释放互斥锁

创建了两个实例Singleton。每个线程都返回自己的实例。

在 L3 的检查中,步骤 8 不会发生,因为在步骤 7 线程 2 的视图_instance已与线程 1 同步,因此只创建了一个实例Singleton

于 2015-10-30T03:27:24.773 回答