【问题标题】:Java : Volatile variable accessJava:可变变量访问
【发布时间】:2012-08-04 15:09:15
【问题描述】:

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

【问题讨论】:

  • 看了那个帖子后我不是很清楚,所以我打开了这个问题。我实际上是在询问更多关于工作流程和内存访问而不是概念本身的信息
  • 很抱歉,但我认为值得一提的是volatile 的优点之一是它还确保了原语的原子读取。它在 32 位处理器机器上的 64 位变量(如 longdouble)的情况下很有用,因为它们可以防止在读取变量的前 32 位和后 32 位之间更新变量。
  • 感谢您的留言。未声明为 volatile 的 64 位数值变量(double 和 long)。

标签: java volatile non-volatile


【解决方案1】:

假设您有一个可以被多个线程访问的变量。

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

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

【讨论】:

  • 说共享内存是指堆?和线程本地内存是指每个线程上的堆栈?那个变量的副本去哪里了?
  • 物理上的去向取决于 JVM 的实现。我们不知道也不关心它的去向。我们所知道的是允许线程缓存变量,但如果它们是易失的,它们就不能。
  • 好的,如果我使用 Lock 而不是 Volatile 怎么办?是否会像线程一样在其本地堆栈上复制变量,并在退出锁后将该变量(可变)更新到共享内存,以便下一个线程始终看到最新的值?
  • 如果您使用锁而不是易失性,那么您可以保证在您使用它时没有其他人覆盖您的值。例如,如果在给定的方法中,您必须使用它的值四次,如果在该方法的中途某个其他线程更改了您的变量,那就不好了。但是,如果您不需要以这种方式使用它,那么锁就大材小用了。
  • 正确我理解这个概念。我只是想澄清并确认每个线程在退出锁定后如何将值设置回共享内存,以便下一个传入线程将看到该最新值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2012-05-09
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多