Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Multithreading - Fatal编程技术网

在Java中何时不使用volatile变量

在Java中何时不使用volatile变量,java,multithreading,Java,Multithreading,我理解volatile变量只能保证可见性,不应用于原子/复合操作。然而,我想我读到了一些只有一个线程在更新值(在单个操作中)时才能使用它的地方。这是正确的吗 所以,如果两个线程正在更新一个易失性变量,那么这个布尔标志是线程安全的吗 我知道可变变量只能保证可见性和可用性 正确的 不应用于原子/复合操作 实际上,所有AtomicXxxx类都使用volatile。他们以安全的方式使用它,这是重要的区别。并非所有操作都是安全的 我想我读过一些文章,其中提到只有一个线程在更新值时才能使用它。这是正确的吗

我理解volatile变量只能保证可见性,不应用于原子/复合操作。然而,我想我读到了一些只有一个线程在更新值(在单个操作中)时才能使用它的地方。这是正确的吗

所以,如果两个线程正在更新一个易失性变量,那么这个布尔标志是线程安全的吗

我知道可变变量只能保证可见性和可用性

正确的

不应用于原子/复合操作

实际上,所有AtomicXxxx类都使用volatile。他们以安全的方式使用它,这是重要的区别。并非所有操作都是安全的

我想我读过一些文章,其中提到只有一个线程在更新值时才能使用它。这是正确的吗

这是一个解决办法。如果您只有一个writer,那么对该字段使用
volatile
就可以了

注意:
volatile
赋予任何使用它的操作线程安全性,这是一种常见的误解。e、 g

volatile int[] a = { 0 };

a[0]++; // not thread safe even if you have only 1 writer.
这是因为写入
a
和只有
a
是不稳定的。
a
所指向的任何东西也不是
volatile
这与
final

final int[] a = { 0 };
a = null; // cannot do this
a[0] = 1; // compiles fine, is not final.
我已经为您缩小了场景范围:如果两个线程正在更新一个可变变量,比如布尔标志(在单个操作中,例如,将其设置为true或false),并且没有任何其他形式的同步,那么这个线程是安全的吗

只有当您有一个writer,或者它们都设置为相同的值时,才是安全的。比如说

flag = true; // ok, provided no thread sets it to false.
flag = !flag; // not ok.

这真的取决于你如何使用它。有些用例是这样的,有些则不然。多线程是一个复杂而微妙的问题,所以像“如果有多个编写器线程,就永远不应该使用volatile”这样的笼统概括很难成立。相反,你必须知道volatile给了你什么——同样重要的是,它没有给你什么——然后仔细地将其应用到手头的情况中。这是一个棘手的问题,所以(a)你应该找到一个好的伙伴来编码你和它一起复习,(b)你应该考虑使用一个更高级的结构,比如BuffjQueWang.等等。一般的注释:不像其他语言,特别是C和C++,在Java
volatile
中,volatile实际上提供了一些同步保证。@yshavit我已经为您缩小了场景范围:如果两个线程正在更新一个volatile变量,比如布尔标志(在单个操作中,例如,将其设置为true或false),并且没有任何其他形式的同步,那么这个线程安全吗?同样,这取决于。它们是否都将其更新为相同的值,基本上作为闩锁?如果不是,如果读取线程错过更新,应用程序是否可以接受?也就是说,如果布尔值从true到false再到true,我的阅读线程只会将其视为true(它从未看到false),可以吗?对于某些用法,它是;对于其他人来说,不是。谢谢你提供的信息,但这并不能解决我的问题。
a
指向的任何东西都是
易失性的
-这不应该是“不是
易失性的
”?@Nier它对于单个编写器来说是唯一线程安全的,就像
x++
AtomicInteger使用compareAndSwap操作。如果是最后一位,如果可以接受错过更新,则也是安全的。举个例子,也许我有一些线程周期性地检查
易失性布尔值isPaused
。我的线程检查并发现它没有暂停,所以它做了一些工作;过了一会儿,它再次检查,发现它仍然没有暂停。它可能不在乎在这两个操作之间,是否有人暂停了它,然后又取消了它。@yshavit还有一个问题,就是你有性能指标,你打印出一个缓存命中率,然后打印出33%的值,如果1000个增量中有1个丢失了,这并不重要,但是,通过不使其变得易变来获得更高的性能可能是值得的。