挥发性的目的/优点

时间:2014-02-22 06:26:14

标签: java multithreading concurrency

您应该使用volatile关键字的具体情况是什么?更重要的是:该计划如何从中受益?

根据我已经阅读和了解的内容:volatile应该用于不同线程访问的变量,因为它们比非易失性线程读取的速度稍快。如果是这样,是否应该有一个关键字来强制反对

或者它们实际上是在所有线程之间同步的吗?正常变量怎么没有?

我有很多多线程代码,我想稍微优化一下。当然我不希望获得巨大的性能提升(无论如何我都没有任何问题),但我总是试图让我的代码更好。我对这个关键字感到有些困惑。

5 个答案:

答案 0 :(得分:8)

当一个多线程程序正在运行时,并且有一些未声明为volatile的共享变量时,这些线程所做的是创建该变量的本地副本,而是在本地副本上工作。因此,变量的变化不会反映出来。创建此本地副本是因为与从主内存访问变量相比,缓存内存访问速度要快得多。

当您将变量声明为volatile时,它会告诉程序 NOT 创建变量的任何本地副本,并直接从主内存使用变量。

通过将变量声明为volatile,我们告诉系统它的值可以从任何地方意外地改变,所以总是使用保存在主存储器中的值并始终更改变量的值在主内存中并没有创建变量的任何本地副本。

请注意,volatile不能代替同步,并且当一个字段被声明为volatile时,编译器和运行时会注意到该变量是共享的,并且对它的操作不应该与其他内存操作重新排序。易失性变量不会缓存在寄存器或缓存中,而是隐藏在其他处理器中,因此读取volatile变量始终会返回任何线程的最新写入。

答案 1 :(得分:2)

易失性使得每次从内存中实际访问每个线程的值都可以更慢地访问变量,从而获得最新的值。

从不同的线程访问变量时,这很有用。

使用分析器调整代码并阅读Tips optimizing Java code

答案 2 :(得分:2)

volatile关键字表示编译器每次引用时都会强制重新读取变量。当该变量不是标准内存时,这很有用。以嵌入式系统为例,您可以在其中读取硬件寄存器或接口,该接口显示为处理器的存储位置。如果处理器使用先前读取的缓存值,则无法正确读取更改该寄存器值的外部系统更改。使用volatile强制执行新读取并保持所有内容同步。

答案 3 :(得分:1)

Here是一个很好的堆栈溢出解释

Here是一篇很好的wiki文章

  

在计算机编程中,特别是在C,C ++,C#和Java编程语言中,使用volatile关键字声明的变量或对象通常具有与优化和/或线程相关的特殊属性。一般来说,volatile关键字旨在阻止编译器应用它可能已经应用的某些优化,因为通常认为变量不能“自己”改变值。

** ^维基

简而言之,它保证给定的线程访问某些数据的相同副本。一个线程中的任何更改都会立即在另一个线程中显而易见

答案 4 :(得分:1)

volatile涉及内存可见性。写入操作完成后,volatile变量的值对所有读者都可见。有点像关闭缓存。

这是一个很好的堆栈溢出响应:Do you ever use the volatile keyword in Java?

关于具体问题,不同步问题。您仍然需要使用锁定来实现这一目标。正常变量既不同步也不易变。

要优化线程代码,可能值得阅读粒度,乐观和悲观锁定。