在阅读接受的答案How to synchronize or lock upon variables in Java?时,我想到,如果在下面的示例中使用volatile而不是同步块,则行为会改变。我想确保消息始终返回正确的值。
让我使用相同的示例:注意,现在我已经在get方法中删除了同步块,并将变量消息标记为volatile。
class Sample {
private volatile String message = null;
private final Object lock = new Object();
public void newMessage(String x) {
synchronized (lock) {
message = x;
}
}
public String getMessage() {
return message;
}
}
}
如果要更改上面显示的代码,是否应该保证相同的行为?两种方法之间有什么区别吗?
提前谢谢
答案 0 :(得分:1)
在这种情况下,volatile
关键字就足够了,因为它为读写建立了事前发生的关系,从而保证一个线程中的写入将被另一个线程中的后续读取所观察。
synchronized
块不正确,但是是多余的。另外,如果您确实使用synchronized
,则可以将消息变量标记为非易失性。但是要小心,并确保读取也位于synchronized
块中,否则会导致数据争用。保证synchronized
块中一个线程进行的非易失性写入对于随后在同一监视器上进入synchronized
块的线程可见。
最后一点要注意,synchronized
块的进度条件与volatile
的读写条件不同。前者阻止(互斥),而后者则无需等待。