关注
volatile 可以保证线程可见性且提供了一定的有序性,但是无法保证原子性。在 JVM 底层是基于内存屏障实现的。
1. 当对非 volatile 变量进行读写的时候,每个线程先从内存拷贝变量到 CPU 缓存中。如果计算机有多个CPU,每个线程可能在不同的 CPU 上被处理,这意味着每个线程可以拷贝到不同的 CPU cache 中
2. 而声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步,所以就不会有可见性问题: (1) 对 volatile 变量进行写操作时,会在写操作后加一条 store 屏障指令,将工作内存中的共享变量刷新回主内存;
(2)对 volatile 变量进行读操作时,会在写操作后加一条 load 屏障指令,从主内存中读取共享变量;
通过 hsdis 工具获取 JIT 编译器生成的汇编指令来看看对 volatile 进行写操作CPU会做什么事情,还是用上边的单例模式,可以看到(如图)
有 volatile 修饰的共享变量进行写操作时会多出第二行汇编代码,该句代码的意思是对原值加零,其中相加指令addl前有 lock 修饰。通过查IA-32架构软件开发者手册可知,lock前缀的指令在多核处理器下会引发两件事情:
1. 将当前处理器缓存行的数据写回到系统内存
2. 这个写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效
正是 lock 实现了 volatile 的「防止指令重排」「内存可见」的特性
查看原帖
点赞 评论
相关推荐
点赞 评论 收藏
分享
点赞 评论 收藏
分享
2024-12-24 21:25
合肥工业大学 Java 点赞 评论 收藏
分享
牛客热帖
更多
正在热议
更多
# 我的2024牛客高光时刻 #
99690次浏览 1551人参与
# 格力求职进展汇总 #
162281次浏览 1219人参与
# 客路2025全球产研实习生招聘 #
74057次浏览 265人参与
# 被同事甩锅了怎么办 #
15924次浏览 90人参与
# 2023毕业生求职有问必答 #
135444次浏览 1346人参与
# 机械人,你的秋招第一份简历被谁挂了 #
121796次浏览 1892人参与
# 打工人锐评公司红黑榜 #
115612次浏览 802人参与
# 通信/硬件公司求职体验 #
89716次浏览 733人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
18798次浏览 404人参与
# 应届生初入职场,求建议 #
152993次浏览 2279人参与
# AI了,我在打一种很新的工 #
36193次浏览 771人参与
# 你的秋招第一场笔试是哪家 #
50374次浏览 587人参与
# 如果校招重来我最想改变的是 #
201207次浏览 2457人参与
# 以前保安读大学现在毕业做保安 #
3751次浏览 22人参与
# 投格力的你,拿到offer了吗? #
60400次浏览 489人参与
# 你认为工作的意义是什么 #
83570次浏览 703人参与
# 机械制造面试记录 #
167374次浏览 2004人参与
# 面试时被问的最奇葩的问题 #
10256次浏览 75人参与
# 牛友投递互助,不漏校招机会 #
226866次浏览 3163人参与
# 如果实习可以转正,你会不会放弃秋招 #
393150次浏览 3481人参与
# 如果再来一次,你还会学硬件吗 #
99715次浏览 1204人参与