Java 如果我在单核机器上运行应用程序,volatile关键字有用吗?

Java 如果我在单核机器上运行应用程序,volatile关键字有用吗?,java,multithreading,volatile,cpu-cache,Java,Multithreading,Volatile,Cpu Cache,我最近熟悉了volatile关键字,我发现不直接从主存读取会导致不一致和所谓的可见性问题 我相信CPU缓存不是特定于任何线程的。所以我想知道在单核处理器中,volatile关键字是否有用?好吧,单处理器或多处理器(核心)肯定会影响整个程序有效并行运行的能力,您仍然可以创建多个线程,它们将拥有自己的缓存,volatile关键字仍将按预期运行-JLS不会为关键字指定处理器相关的行为更改 请注意,唯一不同的是有效并行,这不是关键字行为的决定因素。好吧,单处理器或多处理器(核心)肯定会影响整个程序有效并

我最近熟悉了
volatile
关键字,我发现不直接从主存读取会导致不一致和所谓的可见性问题


我相信CPU缓存不是特定于任何线程的。所以我想知道在单核处理器中,
volatile
关键字是否有用?

好吧,单处理器或多处理器(核心)肯定会影响整个程序有效并行运行的能力,您仍然可以创建多个线程,它们将拥有自己的缓存,
volatile
关键字仍将按预期运行-JLS不会为关键字指定处理器相关的行为更改


请注意,唯一不同的是有效并行,这不是关键字行为的决定因素。

好吧,单处理器或多处理器(核心)肯定会影响整个程序有效并行运行的能力,您仍然可以创建多个线程,它们将拥有自己的缓存,
volatile
关键字仍将按预期运行-JLS不会为关键字指定处理器相关的行为更改


请注意,唯一不同的是有效地并行,这不是关键字行为的决定因素。

硬件级并发显然是规范动机的一个重要部分,但规范非常清楚,要求适用于整个系统;因此,例如,JVM的“实时”(JIT)编译器可以合法地优化

while (this.var) {
    ... code that provably never modifies var ...
}
if (this.var) {
    while (true) {
         ... code that provably never modifies var ...
    }
}
相当于

while (this.var) {
    ... code that provably never modifies var ...
}
if (this.var) {
    while (true) {
         ... code that provably never modifies var ...
    }
}

如果
var
不是
volatile

硬件级别的并发性显然是规范动机的一个重要部分,但是规范非常清楚,要求适用于整个系统;因此,例如,JVM的“实时”(JIT)编译器可以合法地优化

while (this.var) {
    ... code that provably never modifies var ...
}
if (this.var) {
    while (true) {
         ... code that provably never modifies var ...
    }
}
相当于

while (this.var) {
    ... code that provably never modifies var ...
}
if (this.var) {
    while (true) {
         ... code that provably never modifies var ...
    }
}

如果
var
不是
volatile

您想知道CPU缓存在多核处理器中是否有用?或者,您想知道是否需要在一台只有一个cpu和一个内核的机器上使用
volatile
(可能是在某种专门的操作系统上使用单任务)?我想知道您希望得到什么样的答案。据我所知,内存模型和语言规范没有提到内核数量对执行结果的重要性(它们有时被称为可能出错的示例,是的)。需要提到的是,一致性只有在线程之间存在“关系之前发生”时才会发生。如果您想要(线程)安全的代码,请在读/写代码时记住“之前发生”,而不是“我的CPU中与JVM和OS之间共享缓存的可能性相关的内核数量在这个给定的体系结构上实现线程”,这可能更难解释@ElliottFrisch很抱歉说不清楚。我想知道使用volatile关键字是否会对单核处理器编码器产生影响,这将取决于JVM实现的复杂细节和特定处理器的性质。有一种像Java这样的语言,可以精确地指定
volatile
的功能以及您需要它的时间,这样您就不必担心类似的事情了。您想知道CPU缓存在多核处理器中是否有用?或者,您想知道是否需要在一台只有一个cpu和一个内核的机器上使用
volatile
(可能是在某种专门的操作系统上使用单任务)?我想知道您希望得到什么样的答案。据我所知,内存模型和语言规范没有提到内核数量对执行结果的重要性(它们有时被称为可能出错的示例,是的)。需要提到的是,一致性只有在线程之间存在“关系之前发生”时才会发生。如果您想要(线程)安全的代码,请在读/写代码时记住“之前发生”,而不是“我的CPU中与JVM和OS之间共享缓存的可能性相关的内核数量在这个给定的体系结构上实现线程”,这可能更难解释@ElliottFrisch很抱歉说不清楚。我想知道使用volatile关键字是否会对单核处理器编码器产生影响,这将取决于JVM实现的复杂细节和特定处理器的性质。有一种像Java这样的语言,可以精确地指定
volatile
的功能以及您需要它的时间,这样您就不必担心类似的事情。CPU缓存是一种物理硬件,所以我不明白你怎么能声称每个Java软件线程都有自己的线程。@ruakh:CPU缓存有什么问题?这就是操作系统所能有效处理的。在JVM级别上,假设线程维护一个缓存的变量副本是很安全的,这就是volatile关键字发挥作用的地方。@ruakh:几乎每个CPU都有寄存器,当保存中间结果时,寄存器就像缓存一样工作,它们是线程本地的,因为操作系统的任务调度器负责让每个任务像拥有自己的CPU一样运行。此外,JVM的优化器的工作原理类似于添加缓存,在假定顺序一致性的情况下消除冗余操作(并在缺少
volatile
)的情况下忽略潜在的并发更新)。请参阅,如果在(!quit){doSomething();}时有一个类似
的循环,并且
quit
未声明
volatile
,JVM的优化器可能会将
doSomething()
的代码内联到循环中,检测到它没有修改
quit
,并优化代码