C# 和 Java 都定义了
* volatile 读取具有获取语义
* volatile 写入具有释放语义
我的问题是:
- Is this the only correct way to define volatile.
- If not, will things be awfully different if the semantics were reversed, that is
- volatile reads have release semantics
- volatile writes have acquire semantics
最佳答案
volatile
语义背后的原因源于 Java Memory Model ,这是根据操作指定的:
- 读写变量
- 锁定和解锁监视器
- 开始和加入线程
Java 内存模型定义了一个 partial ordering称为 happens-before 表示可以在 Java 程序中发生的操作。通常无法保证线程可以看到彼此操作的结果。
假设您有两个操作A 和B。为了保证执行操作 B 的线程可以看到操作 A 的结果,A 和 B 之间必须存在happens-before 关系。否则, JVM 可以随意重新排序它们。
未正确同步的程序可能会出现数据争用。当一个变量被 >= 1 个线程读取并被 >= 1 个线程写入时,就会发生数据竞争,但读取和写入操作未通过 happens-before 排序进行排序。
因此,正确同步的程序没有数据竞争,程序中的所有操作都按固定顺序发生。
所以 Action 一般只有部分有序,但也有一个全部顺序:
- 锁的获取与释放
- 读写volatile变量
这些 Action 是完全有序的。
This makes it sensible to describe happens-before in terms of "subsequent" lock acquisitions and reads of volatile variables.
关于您的问题:
- 有了 happen-before 关系,您就有了
volatile
的替代定义 - 颠倒顺序对上述定义没有意义,特别是因为涉及总顺序。
This illustrates the happens-before relation when two threads synchronize using a common lock. All the actions within thread A are ordered by the program order rule, as are the actions within thread B. Because A releases lock M and B subsequently acquires M, all the actions in A before releasing the lock are therefore ordered before the actions in B after acquiring the lock. When two threads synchronize on different locks, we can't say anything about the ordering of actions between themthere is no happens-before relation between the actions in the two threads.
关于c# - Java 和 C# 中可变语义背后的原因是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11353274/