ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

第040篇 volatile:可见性、有序性与禁止重排

第040篇 volatile:可见性、有序性与禁止重排 volatile 这题的特别之处在于,它能把"看过资料"和"写过代码"区分开。前者的回答停在名词——可见性、有序性;后者的回答里有执行路径、有数据流向、有失败模式。面试官要的正是后者,而这两种回答之间的差距,比这道题本身的难度大得多。先把结论放在前面:volatile解决两件事——可见性和有序性,唯独不解决原子性。机制上它靠内存屏障实现:写操作后面插入写屏障,强制把改动刷到主存;读操作前面插入读屏障,强制从主存取值;同时禁止编译器与 CPU 对涉及该变量的指令做特定方向的重排。理解这三层,尤其要理解"原子性缺失"的根因,才能把count++为什么不对讲清楚。机制拆解讲清有序性这一层,因为它比可见性更常被讲错。volatile提供的保证是"有序",不是"立即执行"。它禁止的是同一条指令流中越过 volatile 读写的重排,编译器对普通变量允许把写操作延后合并,CPU 也允许让写先在缓存里待一会儿。 另一个容易被忽略的点是指令重排分为三类:编译器重排、单处理器内重排、处理器之间的重排;volatile靠屏障同时约束这三类,而不仅是"禁止编译器优化"。面试里能自己补出这个划分,说明不是死记硬背。这些坑的正确绕法最常见的坑是用 volatile 修饰计数器做自增,压测结果小于期望值,误以为虚拟机有问题。根因是
返回列表