Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java volatile实际上是如何工作的?_Java_Concurrency_Volatile - Fatal编程技术网

Java volatile实际上是如何工作的?

Java volatile实际上是如何工作的?,java,concurrency,volatile,Java,Concurrency,Volatile,在Java中将变量标记为volatile可确保每个线程都能看到上次写入它的值,而不是某个过时的值。我想知道这是如何实现的。JVM是否发出特殊指令来刷新CPU现金或其他东西?确切地说,发生的是处理器特定的。通常有一些形式的内存屏障指令。刷新整个缓存显然非常昂贵——硬件中有缓存一致性协议 同样重要的是,未对现场访问进行某些优化。编译器在考虑多线程时很重要,不要只考虑硬件。确切地说,所发生的事情是特定于处理器的。通常有一些形式的内存屏障指令。刷新整个缓存显然非常昂贵——硬件中有缓存一致性协议 同样重要

在Java中将变量标记为volatile可确保每个线程都能看到上次写入它的值,而不是某个过时的值。我想知道这是如何实现的。JVM是否发出特殊指令来刷新CPU现金或其他东西?

确切地说,发生的是处理器特定的。通常有一些形式的内存屏障指令。刷新整个缓存显然非常昂贵——硬件中有缓存一致性协议


同样重要的是,未对现场访问进行某些优化。编译器在考虑多线程时很重要,不要只考虑硬件。

确切地说,所发生的事情是特定于处理器的。通常有一些形式的内存屏障指令。刷新整个缓存显然非常昂贵——硬件中有缓存一致性协议


同样重要的是,未对现场访问进行某些优化。编译器在考虑多线程时很重要,不要只考虑硬件。

据我所知,它总是看起来好像在写入后刷新了缓存,并且总是看起来好像在读取时直接从内存执行读取。其效果是,一个线程将始终看到来自另一个线程的写入结果,而(根据Java内存模型)永远不会看到缓存值。然而,实际的实现和CPU指令在不同的体系结构中会有所不同

如果在多个线程中增加变量,或者检查其值并采取一些措施,则无法保证正确性,因为显然没有实际的同步。通常,只有当只有线程写入变量,而其他线程都在读取变量时,才能保证正确执行

还请注意,64位非易失性变量可以作为两个32位变量进行读/写,因此32位变量在写入时是原子变量,而64位变量则不是。一半可以写在另一半之前,因此读取的值可以是旧值或新值的倒数

这是我的书签中非常有用的一页:


据我所知,缓存总是在写入后被刷新,并且总是在读取时直接从内存进行读取。其效果是,一个线程将始终看到来自另一个线程的写入结果,而(根据Java内存模型)永远不会看到缓存值。然而,实际的实现和CPU指令在不同的体系结构中会有所不同

如果在多个线程中增加变量,或者检查其值并采取一些措施,则无法保证正确性,因为显然没有实际的同步。通常,只有当只有线程写入变量,而其他线程都在读取变量时,才能保证正确执行

还请注意,64位非易失性变量可以作为两个32位变量进行读/写,因此32位变量在写入时是原子变量,而64位变量则不是。一半可以写在另一半之前,因此读取的值可以是旧值或新值的倒数

这是我的书签中非常有用的一页:


相关问题(实际上是列表中的第一个…)和我在volatile上开始的一个线程,其中有很多关于无序执行的“向上投票”和“收藏夹”:相关问题(实际上是列表中的第一个…)和我在volatile上开始的一个线程,其中有很多“向上投票”和“收藏夹”关于无序执行:@jgubby:您的最后一段似乎不正确:您无法读取一次写入32位,另一次写入32位的64位volatile。@wizadofodds:同意。我想说的是非易失性变量。@jbuggy:ah,我就是这么想的,但我不敢编辑你的帖子,因为我不确定你的意思:)很乐意帮忙,否则会有点困惑:))看到另一个线程的写操作取决于发生之前的关系。如果不违反“先发生后发生”规则,则对volatile的更新不一定立即进行。例如,如果在两次写入之前没有其他操作发生,编译器可以将两次写入合并到一个volatile中。@jgubby:您的最后一段似乎不正确:您无法读取一个64位volatile,该volatile在一次写入中有32位,在另一次写入中有32位。@WizardOfODS:同意。我想说的是非易失性变量。@jbuggy:ah,我就是这么想的,但我不敢编辑你的帖子,因为我不确定你的意思:)很乐意帮忙,否则会有点困惑:))看到另一个线程的写操作取决于发生之前的关系。如果不违反“先发生后发生”规则,则对volatile的更新不一定立即进行。例如,如果在两次写入之前没有其他操作发生,编译器可以将两次写入合并到一个volatile中。正确编写的Java程序中发生的事情不是特定于处理器的。@jgubby问题询问是否发出了特殊指令。正确编写的Java程序中发生的事情不是特定于处理器的。@jgubby问题是问是否发出了特殊指令。