java - 关于 volatile 和 synchronized

标签 java multithreading synchronized volatile

在阅读了一堆关于这个主题的问题/文章之后,我仍然不清楚一件事。

据我了解(如果我错了请纠正我)变量的值可以在本地缓存到线程,因此如果一个线程更新该变量的值,则此更改可能对另一个线程不可见线。 volatile 的使用本质上是强制所有线程从同一位置读取变量的值。此外,关于该主题的所有文献都指出,对该变量进行同步将产生相同的效果。

我的问题是,我读过的任何内容都没有明确说明在不同 变量上进行同步会导致相同的行为,但经常提供一个代码示例,说明在以下两种情况下从变量中读取将是最新的:

volatile int x;
...
int y = x;

final Object lock = new Object();
int x;
...
synchronized(lock) {
    int y = x;
}

接下来的问题是:对任意变量进行同步是否会强制同步块(synchronized block)中的每个变量访问都访问该变量的最新值?

最佳答案

is it the case that synchronizing on any arbitrary variable will force every variable access within the synchronized block to access the most up to date value of that variable?

您可以在任何变量上同步读取,只要该变量的写入是在同一变量的同步下完成的。

在您的示例中,只要发生类似以下的事情,那么在写入 x 之前发生的所有写入都将在后续读取之后可见:

synchronized(lock){
   x = 10;
}

所以对于你之前的观点:

...nothing I've read ever explicitly states that synchronizing on a different variable will cause this same behavior...

那是因为它不提供相同的行为。之前发生的关系发生在少数情况下,在您的情况下有两个重要的是

  1. 写入并随后读取相同的 volatile 变量
  2. 同一对象上监视器的退出和后续进入

关于java - 关于 volatile 和 synchronized,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19030647/

相关文章:

hibernate - Spring事务可以使同步方法不同步吗?

java - 为什么我的同步方法不能正常工作?

Java线程: start and sleep threads at random time

c# - 循环内的异步/等待会造成瓶颈吗?

java - 迭代列表并将 Callables 提交到 ExecutorService

java - ArrayList 中的 ConcurrentModification 异常

java - 解析时日期正在更改

Java Spring 和 Google App Engine

java - 为什么 Handler 不工作而 Listener 工作?

java - 使用cn1 toolBar后无法使用Android原生的back命令