0

为什么我们需要在原语上使用 volatile?我发现的最常见的例子

volatile boolean shutdownRequested;

...

public void shutdown() { shutdownRequested = true; }

public void doWork() { 
    while (!shutdownRequested) { 
        // do stuff
    }
}

但是当我试图自己运行它时。易失性声明没有任何改变。它以易失性和非易失性停止shutdownRequested

4

5 回答 5

4

本质上, volatile 用于指示变量的值将被不同的线程修改。

一个 volatile Java 变量意味着:

这个变量的值永远不会被缓存到线程本地:所有的读写都将直接进入“主内存”;并且对变量的访问就像它被包含在一个同步块中一样,在其自身上同步。

于 2013-04-03T11:55:39.937 回答
2

未标记的变量volatile可以根据 JVM 的意愿缓存。例如,可以将变量的副本加载到寄存器中,然后可能永远不会引用原始实例变量,尤其是在紧密循环中。

将其标记为volatile告诉 JVM 它必须始终引用原始实例变量。

您所看到的可能只是 JVM 没有缓存变量,即使它是允许的。

这也是多线程代码难以证明正确的原因之一。不仅并非所有 JVM 都以相同的方式工作,而且与运行代码时相比,调试代码时甚至可能会得到不同的结果,如果它在多核单元上运行,它可能再次以不同的方式运行。

于 2013-04-03T11:58:30.777 回答
0

volatile对于多线程代码很有用。

看到这个问题:你曾经在 Java 中使用过 volatile 关键字吗?

于 2013-04-03T11:57:15.167 回答
0

对 volatile 变量的更改始终对其他线程可见。在此处输入链接描述

在您的示例中,一个线程正在执行 doWork() 并且另一个线程出现并调用关闭。在某些平台上的某些 JVM 上,编译器可能会以这样一种方式优化事物,即工作线程看不到对 shutdownRequested 变量的更改,例如,该变量可能被缓存在寄存器中。

于 2013-04-03T11:58:01.883 回答
0

volatile当您想确保正在读取的值是当前值,没有任何缓存时,您应该使用变量。

于 2013-04-03T11:59:32.143 回答