我认为在没有其他线程同步的情况下,对共享可变状态的所有访问必须使用某种形式的低级线程安全性(例如内存屏障)以避免操作重新组织(无论是通过编译器,JIT还是CPU)?
例如,在C#中,我必须在任何地方使用Volatile.Read(ref someVar)和Volatile.Write(ref someVar,someValue)吗?我不使用任何其他类型的同步?
我觉得答案是是,我必须这样做。但似乎......过度。
一张纸条,在任何人加入之前: 我不是在谈论线程安全或并发性;只是记忆的一致性我很清楚在编写多线程代码时,内存一致性并不是唯一的问题。
答案 0 :(得分:1)
首先,如果你声明变量volatile,你可以正常读/写它们并获得内存障碍。
对于实际问题:取决于您如何定义“内存一致性”。根据您的使用情况,您不必同步每次写入/读取,您可以只使用一个来确保一次发布多个内容:
// T1:
foo = 5 // non-volatile
bar = 7 // non-volatile
done = True // volatile write
// T2:
if (done) { // volatile read
foo and bar guaranteed to be 5, respectively 7 with non-volatile reads
}
但是,你仍然需要每个线程至少有一个内存屏障,否则你的代码会“出错”。但那取决于你如何定义“有缺陷”。
我能想到的一个(也是唯一真正的)示例是没有内存保证的宽松CAS,它允许实现不丢弃更新且不强制排序的性能计数器。该特定想法的来源,请参阅here(build.java之前的最后一段)