2012-08-04 121 views
2

我对volatile变量如何有效地从“主”内存访问有点困惑。它与具有本地副本的变量(非易失性)有什么不同?多线程访问非易失性vs是一个易失性变量时,典型的工作流程是什么?我的意思是他们如何在幕后工作?Java:易变变量访问

+0

可能重复的[Java中的易失性关键字 - 澄清](http://stackoverflow.com/questions/3603157/volatile-keyword-in-java-澄清) – Mat 2012-08-04 15:15:22

+0

在读完该线程之后,我并没有那么清楚,所以我打开了这个问题。我实际上更多地询问工作流程和内存访问,而不是概念本身 – peter 2012-08-04 15:20:30

+1

对不起,我认为值得一提的是'volatile'的优点之一是它还可以确保原语的原子读取。对于32位处理器机器中的64位变量(比如'long'或'double')是很有用的,因为它们会阻止在读取变量的前32位和后32位之间更新变量。 – Pshemo 2012-08-04 15:43:30

回答

5

比方说,你有一个可以被多个线程访问的变量。

线程1查看变量。由于查看共享内存比线程本地内存更昂贵,因此它会创建变量的副本。 (请注意,对象不会被复制,只是其参考。)

线程2查看相同的变量。它决定改变这个变量。但是线程1不知道它!线程1仍在使用陈旧的数据。这是一件非常糟糕的事情。通过将其设置为volatile,每个线程在访问时都必须查看原始变量。他们不允许制作本地副本,所以不会过时。

+0

通过说共享内存你是指堆?线程本地内存是指每个线程上的堆栈?该变量的副本在哪里去? – peter 2012-08-04 15:23:27

+0

它在物理上取决于JVM的实现。我们不知道或不在乎它在哪里。我们只知道线程被允许缓存变量,但如果它们是不稳定的,它们不能。 – corsiKa 2012-08-04 15:25:48

+0

好吧如果我使用Lock而不是挥发性物质?是否会像线程在其本地堆栈上创建变量的副本,并且一旦它退出锁定,它将该变量(可变)更新到共享内存,以便下一个线程始终能够看到最新值? – peter 2012-08-04 15:29:11