为临界区设置互斥锁意味着多个线程将无法破坏临界区,但是为什么我们需要volatile变量来处理同一件事呢?
如果下面的代码中没有volatile字会发生什么?
为临界区设置互斥锁意味着多个线程将无法破坏临界区,但是为什么我们需要volatile变量来处理同一件事呢?
如果下面的代码中没有volatile字会发生什么?
该volatile
关键字不提供任何锁定。
其目的是防止编译器优化会“缓存”该值,以便线程可能正在检查过时的数据。
Volatile 在语言之间存在细微差别,并且总是有点问题。仔细阅读您的规格并遵循可信赖的示例。
volatile 关键字使双重检查锁定在 1.5 和更高版本的 JVM 上正常工作,请参阅该页面的新 Java 内存模型部分。
如果没有 volatile 关键字,则可能会在 1.5 和更高版本的 JVM 上创建两个实例。在 1.5 之前的 JVM 上,双重检查锁定被认为是完全损坏的,不应使用。
然而,在初始化单例的情况下,使用双重检查锁定通常被认为是不值得的,简单的静态初始化就足够了。如果您绝对知道单例将在某个时候由您的应用程序初始化,那么惰性实例化是多余的。去吧:
private static Singleton s_instance = new Singleton()
或任何 C++ 等价物。好又安全!
由于这个问题最终导致了 Java 和 C++ 的混乱,请注意,我指的是上面的 Java。在 C++ 中没有 synchronized 关键字,并且 volatile 不适用于并发。