Java:易失性变量访问

Java:易失性变量访问,java,volatile,non-volatile,Java,Volatile,Non Volatile,对于volatile变量如何有效地访问“主”内存,我有点困惑。它与具有本地副本的变量(非易失性)有何不同?当多个线程访问一个非易失变量和一个易失变量时,典型的工作流是什么?我是说他们在幕后是怎么工作的 假设您有一个可由多个线程访问的变量 线程1查看变量。因为查看共享内存比线程本地内存更昂贵,所以它会复制变量。(请注意,不会复制对象,只复制其引用。) 线程2查看相同的变量。它决定更改变量。但是线程1不知道!线程1仍在使用过时数据。这是一件非常糟糕的事情。通过将其设置为volatile,每个线程在访

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

假设您有一个可由多个线程访问的变量

线程1查看变量。因为查看共享内存比线程本地内存更昂贵,所以它会复制变量。(请注意,不会复制对象,只复制其引用。)


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

可能的副本我在读了那篇文章后不太清楚,所以我打开了这个问题。我实际上是在问更多关于工作流和内存访问的问题,而不是它本身的概念。对此我感到很抱歉,但我认为值得一提的是,
volatile
的一个优点是它还可以确保原语的原子读取。对于32位处理器机器上的64位变量(如
long
double
),它很有用,因为它们阻止在读取变量的前32位和后32位之间更新变量。感谢您的说明。未声明为易失性的64位数字变量(双精度和长精度)。说共享内存是指堆?线程本地内存意味着每个线程上的堆栈?变量的副本会去哪里?它的物理位置取决于JVM的实现。我们不知道也不关心它去哪里。我们所知道的是线程可以缓存变量,但是如果它们是易失性的,它们就不能缓存。好吧,如果我使用Lock而不是volatile呢?它是否会像线程在其本地堆栈上复制变量一样,一旦退出锁,它就会将该变量(可变)更新到共享内存中,这样下一个线程将始终看到最新的值?如果使用锁而不是volatile,然后,您可以保证在您使用时没有其他人覆盖您的值。例如,如果在一个给定的方法中,您必须使用它的值四次,如果在该方法进行到一半时,其他线程更改了您的变量,这是不好的。但是,如果你不需要以这种方式使用它,那么锁就太过分了。对,我理解这个概念。我只是想澄清和确认,每个线程在退出锁后如何将值设置回共享内存,以便下一个传入线程看到最新的值。