在高版本 JDK(例如 jdk11、14)中,单例双重检查锁定是否仍然需要 volatile?

xin*_*doo 3 java

在 Java 单例中,大多数人告诉我们我们需要 volatile 来防止指令重新排序,但有人告诉我它在高版本 JDK 中不再需要 volatile,对吗?如果是这样,为什么?

public class SafeDCLFactory {
  private volatile Singleton instance;

  public Singleton get() {
    if (instance == null) {  // check 1
      synchronized(this) {
        if (instance == null) { // check 2
          instance = new Singleton();
        }
      }
    }
    return instance;
  }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 5

在高版本 JDK(例如 jdk11 或 jdk14)中,单例双重检查锁定是否仍然需要 volatile?

是的,它确实。从 Java 5 开始的所有 Java 版本都需要instancevolatile.

(在 Java 5 之前,无论是否instance声明,上述代码都不能可靠地工作volatile。)

... 有人告诉我它不再需要 volatile ...

我会挑战那个“某人”提供可靠的来源(或“之前发生过”的证据)来支持他们的断言。如果它们是正确的,那么构建证明所需的所有信息都在 JLS 17.4 ... 中,适用于相关的 Java 版本。