假设我在同步方法中更新了两个变量的值。在退出同步块之前,其他线程可以看到同步方法中设置的新值是否可见?
public synchronized void setValues(){
a=5;
// assume thread is preempted after this assignment
// would the value 5 be visible to other threads?
// my understanding is that the values will not be flushed to
// main memory until the lock is released- i.e., until the synchronized
// method is complete. So the changes will not be visible to other
// threads even when not using synchronization
b=10;
}
以下方法是不同步,所以我理解线程可能看到陈旧的值。我的问题是,如果线程在分配给a后被抢占,是否有可能在printValues方法中看到变量a的新值“5”?
public void printValues() {
System.out.println(a + " " + b);
}
答案 0 :(得分:13)
是的,在到达synchronized块的末尾之前,在synchronized 中进行的更改可以(但不保证)可见。基本上,在阅读或写入数据时,通常需要同步(在同一个锁上)以获得一致的世界视图。
为同步提供的保证是使“做正确的事”(正确同步)正常工作 - 他们不保证当你不<时,原子地进行更改/ em>做正确的事情(观察共享变量而不同步)。
您可以(在某种程度上)将同步块内的写入视为对OutputStream.write()
的调用,同步块的退出就像flush()
调用一样。当你走过街区的一半时,你写的可能的一些数据已经输出到输出文件(或其他任何东西) - 但它仍然可以被缓冲。这并不意味着表明内存模型是如何实现的,只是为了帮助您了解如何保证可见性。
答案 1 :(得分:0)
synchronized
并不保证会立即刷新a
的值。如果a
是易变的,那就是。