简体   繁体   English

可以使用volatile字段修饰符替换同步读取吗?

[英]Can synchronized read be replaced with volatile field modifier?

While reading the accepted answer How to synchronize or lock upon variables in Java? 在阅读接受的答案时, 如何在Java中同步或锁定变量? , it occurred to me if the behavior would change if one was to use volatile in the below example instead of synchronized block. ,如果在下面的示例中使用volatile而不是同步块,则行为是否会发生改变,这对我来说是偶然的。 I would like to make sure message always return the correct value. 我想确保消息始终返回正确的值。

Let me use this same sample: Note now I've removed the synchronized block in the get method and marked the variable message as 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;
        }
    }
}

Would it warrant the same behavior if one was to change the code as shown above ?. 如果要更改上面显示的代码,是否可以保证相同的行为? Are there any differences between two approaches ? 两种方法之间有什么区别吗?

Thank you in advance 先感谢您

The volatile keyword in this case is enough because it establishes a happens-before relation for the reads and writes, guaranteeing that the write in one thread will be observed by a subsequent read in another thread. 在这种情况下, volatile关键字就足够了,因为它为读写建立了一个事前发生的关系,从而保证了一个线程中的写入将被另一个线程中的后续读取所观察到。

The synchronized block is not incorrect but it is redundant. synchronized块不是不正确,但它是冗余的。 Also, if you do use synchronized , you can mark your message variable as non-volatile. 另外,如果您确实使用synchronized ,则可以将消息变量标记为非易失性。 But be careful and make sure the read is also in a synchronized block, otherwise you have a data race. 但是要小心,并确保读取也处于synchronized块中,否则会导致数据争用。 Non-volatile writes made by one thread in a synchronized block are guaranteed to be visible for threads subsequently entering a synchronized block on the same monitor. 确保一个线程在synchronized块中进行的非易失性写入对于随后在同一监视器上进入synchronized块的线程可见。

As a final note, the synchronized block has different progress conditions than volatile reads and writes. 最后一点, synchronized块与volatile读写的进度条件不同。 The former is blocking (mutual exclusion) while the latter is wait-free. 前者处于阻塞状态(互斥),而后者则无需等待。

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

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