volatile读写能否保证相邻字段可见性?线程场景正确性验证
问题
以下为简单示例,无需解释lock、Interlocked等概念:
该布尔值用于标识state的值是否可用,且state与该布尔值后续不会再被修改。
int state; volatile bool stateAvailable; Thread A: while(!stateAvailable) { sleep } read state Thread B: state = 5; stateAvailable = true;
请问上述场景能否保证线程A总能正确读取state的值?我对该场景下的保证机制存在困惑(仅针对此简单示例):
- volatile写入是否能保证其之前的操作已完成,volatile读取是否能保证其之后的操作不会提前执行,从而同步处理器状态?
- 还是说volatile读写仅能确保编译器不会优化掉线程A中的布尔值检查,而对state可能存在的过期值无影响?
若能指出此问题的重复提问链接,我将不胜感激。
回答
这个场景能保证线程A总能正确读取到state的最新值(也就是5),针对你的困惑具体说明:
第一个问题的答案是肯定的:
volatile读写具备内存屏障语义。Thread B里的stateAvailable = true(volatile写入)会强制确保它之前的state = 5操作已经完成并刷新到主内存,不会被编译器或处理器重排到这个volatile写入之后;Thread A里对stateAvailable的volatile读取,会强制确保它之后的读取state操作不会被重排到读取之前,同时会同步处理器缓存,从主内存获取最新的state值。第二个问题的答案是否定的:
volatile的作用不只是阻止编译器优化。它确实能避免线程A中的布尔值检查被优化(比如不会把stateAvailable缓存到寄存器里不更新),但更核心的是提供了跨线程的内存可见性和指令重排禁止的保证,这直接确保了state的更新对线程A是可见的。
内容的提问来源于stack exchange,提问作者AyCe
相关产品推荐
相关产品推荐

