C# 和 Java 都定义了这一点
* 易失性读取具有获取语义
* 易失性写入具有释放语义
我的问题是:
- 这是定义 volatile 的唯一正确方法吗?
- If not, will things be awfully different if the semantics were reversed, that is
背后的原因volatile
语义植根于Java内存模型 http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html,其指定为actions:
- 读取和写入变量
- 监视器的锁定和解锁
- 启动和连接线程
Java内存模型定义了一个部分排序 http://en.wikipedia.org/wiki/Partially_ordered_set called 发生在之前Java 程序中可能发生的操作。通常不能保证线程可以看到彼此操作的结果。
假设您有两个操作A and B。为了保证执行动作B的线程可以看到动作A的结果,必须有一个发生在之前A 和 B 之间的关系。如果没有,JVM 可以自由地reorder他们随心所欲。
未正确同步的程序可能会出现数据争用。当变量由 > 1 个线程读取并由 >= 1 个线程写入时,就会发生数据争用,但读取和写入操作未通过happens-before排序进行排序。
因此,正确同步的程序没有数据竞争,并且程序中的所有操作都按固定顺序发生。
所以动作一般只是部分地已订购,但还有一个total订单之间:
这些动作都是完全有序的。
这使得描述变得合理发生在之前就“后续”锁定获取和易失性变量的读取而言。
关于您的问题:
- 通过事前发生的关系,你有一个替代的定义
volatile
- 颠倒顺序对于上面的定义来说没有意义,特别是因为涉及到总顺序。
这说明了当两个线程使用公共线程同步时的发生前关系lock。线程 A 内的所有操作都是按程序顺序规则排序,线程 B 内的操作也是如此。因为 A 释放了锁 M 和 B随后获取M,因此释放锁之前A中的所有动作都是之前订购过获取锁后B中的动作。当两个线程同步时不同的锁,我们不能说任何关于它们之间的操作顺序的事情,两个线程中的操作之间没有发生之前的关系。
Source: Java 并发实践 http://jcip.net/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)