C#中volatile写入的可见性保障:规范是否明确界定?
C# Volatile字段可见性的规范依据
在ECMA 334第6版中,volatile字段的可见性保障并非隐含,而是由内存模型章节和volatile的获取/释放语义共同明确规定的:
首先,14.5.4节定义的volatile读的「获取语义」和volatile写的「释放语义」本身就包含可见性约束:
- 释放语义的写操作:要求该写操作完成前的所有内存操作(比如示例中
result = 143),对后续执行获取语义读操作的线程完全可见。 - 获取语义的读操作:要求该读操作必须读取到内存中的最新值(而非线程本地缓存的旧值),且后续的内存操作能看到该读操作同步到的所有前置操作结果。
- 释放语义的写操作:要求该写操作完成前的所有内存操作(比如示例中
其次,规范的10.4.5 内存模型章节明确了线程间的同步可见性规则:当线程A的一个释放操作与线程B的一个获取操作形成「同步关系」时,线程A在释放操作前的所有写操作,对线程B都是可见的。而volatile写属于释放操作,volatile读属于获取操作,二者天然构成同步关系——这就直接保障了:
- Thread2中
finished = true的volatile写,最终会被主线程的finishedvolatile读读取到; - Thread2中在
finished写之前的result = 143,也会被主线程在读取finished之后的result读取看到。
- Thread2中
回到你给出的示例,主线程的if (finished)是volatile读(获取语义),它会强制从内存中读取finished的最新值,而不是使用缓存的旧值;同时因为Thread2的finished = true是volatile写(释放语义),且发生在result = 143之后,所以主线程一旦读到finished为true,就能确保result的值已经是143。
内容的提问来源于stack exchange,提问作者Malt
相关产品推荐
相关产品推荐

