C# 和 Java 都定义了以下规则:
* volatile 读取具有获取语义
* volatile 写入具有释放语义
我的问题是:
- 这是唯一正确的定义 volatile 的方式吗?
- 如果不是,如果语义被颠倒,会有很大的区别吗?即
- volatile 读取具有释放语义
- volatile 写入具有获取语义
C# 和 Java 都定义了以下规则:
* volatile 读取具有获取语义
* volatile 写入具有释放语义
我的问题是:
- 这是唯一正确的定义 volatile 的方式吗?
- 如果不是,如果语义被颠倒,会有很大的区别吗?即
- volatile 读取具有释放语义
- volatile 写入具有获取语义
volatile
语义的原因源于Java Memory Model,该模型是以操作为基础进行规定的:
Java Memory Model 为可以在 Java 程序中发生的操作定义了一个称为happens-before的partial ordering。通常情况下,没有保证线程可以看到彼此操作的结果。
假设您有两个操作A和B。为了保证执行操作 B 的线程可以看到操作 A 的结果,必须存在happens-before关系。如果不存在,JVM 可以根据自己的意愿重新排序它们。
一个未正确同步的程序可能会出现数据竞争。当一个变量被大于1个线程读取并被大于等于1个线程写入时,但是读取和写入操作没有通过happens-before排序进行排序时,就会发生数据竞争。来源:Java并发实践