在阅读已接受的答案时How to synchronize or lock upon variables in Java? ,我想到如果在下面的示例中使用 volatile 而不是同步块(synchronized block),行为是否会改变。我想确保消息始终返回正确的值。
让我使用相同的示例:请注意,现在我已经删除了 get 方法中的同步块(synchronized block),并将变量消息标记为 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;
}
}
}
如果要更改如上所示的代码,是否会保证相同的行为?两种方法之间有什么区别吗?
提前谢谢
最佳答案
在这种情况下,volatile
关键字就足够了,因为它为读取和写入建立了发生前关系,保证一个线程中的写入将被另一个线程中的后续读取观察到。
synchronized
block 没有不正确,但它是多余的。另外,如果您确实使用synchronized
,则可以将消息变量标记为非 volatile 。但要小心并确保读取也在同步块(synchronized block)中,否则会出现数据竞争。一个线程在同步块(synchronized block)中进行的非 volatile 写入保证对于随后进入同一监视器上的同步块(synchronized block)的线程可见。
最后一点,synchronized
block 的进度条件与 volatile
读取和写入不同。前者是阻塞的(互斥),后者是免等待的。
关于java - 同步读可以用 volatile 字段修饰符代替吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56904832/