Java中的“易失性”是什么意思?
我们在其中一个项目中使用维护由不同线程访问的变量的相同副本。我的问题是是否可以与.编译器没有给出任何错误,但我不明白使用两者的原因。volatile
volatile
static
我们在其中一个项目中使用维护由不同线程访问的变量的相同副本。我的问题是是否可以与.编译器没有给出任何错误,但我不明白使用两者的原因。volatile
volatile
static
除了阅读内存型号规格外,我建议您阅读 http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html。它是由JMM作者之一撰写的,应该可以回答您的问题。根据happened-before子句来考虑内存读取和写入也是有帮助的;Java 5 及更高版本的 JMM 将 happen-before 语义添加到 。volatile
具体来说,当您从一个线程读取易失性变量时,所有写入(包括从其他线程写入该易失性变量)现在对该线程都是可见的。
而且,是的,您可以将静态
与 .他们做不同的事情。volatile
在Java中,volatile具有与C中类似的一般含义。Java内存模型(参见ide答案中的优秀链接)允许线程同时“看到”标记为非易失性的变量的不同值。例如:
线程 a:
n = 1;
// wait...
n = 2;
线程 B 和 C:
while (true) {
System.out.println(name + ": " + n);
}
允许此输出发生(请注意,您不能保证在B和C之间严格交替,我只是试图在这里显示B和C的“转换”):
C: 1
B: 1
C: 2
B: 1
C: 2
B: 2
这与 由 采取的锁完全分开;即使 C 发现线程 B 是 2,也允许将线程 B 视为 1。有各种各样的非常好的理由,我不能假装完全理解,许多与速度有关,有些与安全性有关。println
n
如果它是易失性的,你可以保证(除了锁定,我暂时忽略它)B和C将在发送后“同时”看到B的新值。println
您可以使用,因为它们会影响不同的事情。 使更改变量在使用该变量之前“复制”到使用该变量的所有线程,同时在使用该变量的所有类之间共享单个变量。(对于不熟悉Java线程的人来说,这可能会相当混乱,因为每个线程都恰好作为.)volatile
static
volatile
static
Thread
class