java - 同步读可以用 volatile 字段修饰符代替吗?

标签 java concurrency synchronization

在阅读已接受的答案时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/

相关文章:

java - NoSuchMethodError : com. google.common.base.Stopwatch.createStarted()Lcom/google/common/base/秒表

C++0x 内存模型和推测加载/存储

input - 如何在 "not main"进程中从控制台读取

java - 该 Java 程序没有显示预期的死锁

java - 为 setDefaultCloseOperation 创建自定义操作?

java - 从 war 中提取 SymmetricDS 引擎

线程并发

multithreading - 如何在多线程游戏引擎中保持我的世界数据同步?

c++ - 带生产者/消费者模型的文件复制工具

java - CloudBees如何设置多个 "environments"?