关于移除Java volatile关键字后线程读取半写入值的疑问
关于移除volatile后是否会读取到int变量中间值的问题解答
针对你的疑问,直接给出结论:移除volatile后,绝对不会出现读线程读取到非3000也非5000的中间值的情况,原因如下:
int类型的赋值操作在Java中是原子性的
JVM规范明确规定,对于32位的基本类型(包括int、byte、short、char、boolean),变量的赋值操作是单个原子指令,不会被拆分成多个步骤执行。也就是说写线程对responseTimeout的赋值(从3000改成5000)要么完全完成,要么完全没开始,不存在“写了一半”的中间状态,读线程只能读到完整的旧值或新值。你提到的“部分线程读旧值”是可见性问题,和原子性无关
没有volatile时,部分读线程短时间内看到旧值,是因为线程的工作内存没有及时同步主内存的新值,属于缓存一致性导致的可见性延迟,但这和“中间值”是完全不同的概念——延迟看到的还是完整的旧值,不是半写状态的值。额外补充:只有64位基本类型需要注意
如果你使用的是long或double类型,情况会不一样。因为JVM允许在没有volatile修饰的情况下,把64位变量的写操作拆分成两个32位的操作执行,这时候才有可能出现读取到中间值的情况。但你的场景是int类型,完全不用考虑这个问题。
结合你的场景:既然你们可以接受短时间内部分线程读取旧值,那移除volatile是完全可行的,不会出现中间值的风险。
内容的提问来源于stack exchange,提问作者JBalaguero
相关产品推荐
相关产品推荐

