何时对同步块的更改对其他线程可见

时间:2011-06-15 20:38:03

标签: java synchronization

假设我在同步方法中更新了两个变量的值。在退出同步块之前,其他线程可以看到同步方法中设置的新值是否可见?

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);
}

2 个答案:

答案 0 :(得分:13)

是的,在到达synchronized块的末尾之前,在synchronized 中进行的更改可以(但不保证)可见。基本上,在阅读写入数据时,通常需要同步(在同一个锁上)以获得一致的世界视图。

为同步提供的保证是使“做正确的事”(正确同步)正常工作 - 他们保证当你不<时,原子地进行更改/ em>做正确的事情(观察共享变量而不同步)。

您可以(在某种程度上)将同步块内的写入视为对OutputStream.write()的调用,同步块的退出就像flush()调用一样。当你走过街区的一半时,你写的可能的一些数据已经输出到输出文件(或其他任何东西) - 但它仍然可以被缓冲。这并不意味着表明内存模型是如何实现的,只是为了帮助您了解如何保证可见性。

答案 1 :(得分:0)

synchronized并不保证会立即刷新a的值。如果a是易变的,那就是。