简体   繁体   English

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

[英]When are changes in Synchronized block visible to other threads

Say that I update values of two variables in a synchronized method. 假设我在synchronized方法中更新了两个变量的值。 Would it be possible that the new values set in synchronized method be visible to other threads before exiting the synchronized block? 退出synchronized块之前 ,同步方法中设置的新值是否可能对其他线程可见?

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

Below method is not synchronized, so I understand that the thread may see stale values. 下面的方法同步,所以我理解该线程可能会看到陈旧的值。 My question is if the thread is preempted after assignment to a, is it ever possible that the new value "5" for variable a be visible in printValues method? 我的问题是,如果线程在分配给a之后被抢占,那么变量a的新值“5”是否可能在printValues方法中可见?

public void printValues() {
    System.out.println(a + " " + b);
}

Yes, changes made within synchronized can (but aren't guaranteed) to be visible before you get to the end of the synchronized block. 是的,在到达synchronized块的末尾之前,在synchronized can (但不保证)内进行的更改是可见的。 Basically, you usually need to synchronize (on the same lock) when reading or writing data in order to get a consistent view of the world. 基本上,您通常需要在读取写入数据时同步(在同一个锁上),以便获得一致的世界视图。

The guarantees provided for synchronization are to make "doing the right thing" (synchronizing appropriately) work correctly - they don't guarantee that changes are made atomically when you're not doing the right thing (observing the shared variables without synchronizing). 提供同步的保证是使“做正确的事”(适当地同步)正常工作-他们保证改变原子制成,当你没有做正确的事(观察共享变量不同步)。

You can (to some extent) think of the writes within the synchronized block as being like calls to OutputStream.write() with the exit of the synchronized block being like a flush() call. 您可以(在某种程度上)将synchronized块中的写入视为对OutputStream.write()调用,同步块的退出就像flush()调用。 When you're half way through the block, some of the data you've written may have made it to the output file (or whatever) - but it might still be buffered. 当你在块的一半时,你写的一些数据可能已经输出到输出文件(或其他任何东西) - 但它仍然可以被缓冲。 That's not meant to be an indication of how the memory model is implemented, just an analogy to help you understand how the visibility isn't guaranteed. 这并不意味着如何实现内存模型,只是为了帮助您了解如何保证可见性。

The synchronized doesn't guarantee that value of a will be flushed immediately. synchronized不保证将立即刷新a值。 It will be if a is volatile. 如果a是不稳定的话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM