网易首页 > 网易号 > 正文 申请入驻

浅谈synchronized 和 volatitle 实现线程安全的策略

0
分享至

  什么是线程不安全

  对线程安全的理解就是多个线程同时操作一个共享变量时会产生意料之外的情况,这种情况就是线程不安全。注意:只有写操作才可能出现线程不安全,对共享变量只进行读操作线程是绝对安全的。

  具体线程不安全的例子有一个很经典的就是两个线程都对一个共享变量 x=0 执行 100 次自增操作,但是 x 的结果并非 200

  因此线程不安全的条件是:多线程 + 共享变量 + 写操作

  Java的内存模型

  你可能会好奇线程是如何获取共享变量的?

  Java 线程之间的通信由 Java 内存模型(简称 JMM)控制,从抽象的角度来说,JMM 定义了线程和主内存之间的抽象关系。JMM 的抽象示意图如图所示:

  从图中可以看到:

  共享变量存在于主内存中,也就是堆内存

  每一个线程都保存了一份该线程使用到的共享变量的副本

  线程读取共享变量优先从本地内存(也就是栈内存)中读取,写共享变量先写到栈内存,再写入堆内存

  线程之间对共享变量的通信只能通过堆内存

  以上只是 Java 内存模型的抽象图,实际上线程的工作模型是这样的,栈内存即是两个缓冲区

  接下来看一个线程不安全的例子:

  假设线程 A、B 操作同一个共享变量 X,初始两级 Cache 都为空

  线程A想要读取X的值,由于两级 Cache 都没有命中,因此加载堆内存中的 X=0,并缓存到两个 Cache 中

  线程 A 修改 X 的值为 1,为两个 Cache 刷新 X,再刷新到堆内存

  线程 B 想要获取 X 的值,一级缓存没有获取到,二级缓存命中,读取到 X=1

  线程B想要修改X的值为 2,先刷新自,己的一级缓存为 2,再刷新二级缓存和堆内存中的 X 为 2。目前为止一切正常,接下来重点来了

  线程 A 想要读取 X 的值,一级缓存命中此时 X=1,但是堆内存中的 X=2。可以看到线程B写入的共享变量对 X 不可见,出现了线程不安全的情况。

  由于 Java 内存机制就是这样设计的,因此多个线程操作同一个变量会产生不安全的问题,volatitle 关键字这是被设计出来解决这一问题的,它只能用于单个变量。

  volatile解决共享变量线程不安全的策略

  还是接着上面这个例子,这样定义 X

  volatile 的内存语义是:

  当一个线程对 volatile 修饰的变量进行写操作时,JMM 会立即将该线程对应的栈内存中的副本的值刷新到堆内存中;当一个线程对 volatile 修饰的变量进行读时,JMM 会清空此变量的一二级缓存,直接从堆内存中读取共享变量的值。

  volatile 可以当作一个轻量级的锁来使用,但 volatile 仅仅只能保证共享变量内存的可见性,不能保证操作共享变量的原子性,而锁(如 synchronized)能保证整段锁范围内的代码具有原子性。

  synchronized 与锁

  首先要明确的是 synchronized 不是锁,锁都是基于对象的( Object 的子类),Java 中的每一个对象都可以作为一个锁。

  synchronized 是 Java 的一个关键字,保证临界区内的代码同一时刻只能有一个线程执行。

  线程的执行代码在进入 synchronized 代码块前会自动获取内部锁,这时候其他线程访问该同步代码块时会被阻塞挂起。拿到内部锁的线程会在正常退出同步代码块或者抛出异常后或者在同步块内调用了该内置锁资源的wait系列方法时释放该内置锁。内置锁是排它锁,也就是当一个线程获取这个锁后,其他线程必须等待该线程释放锁后才能获取该锁。

  sysnchronized的内部锁可以是:

  当前类的 class 字节码对象:this.getClass

  当前类的一个实例:this

  一个 Object 对象

  wait 和 notify 方法只能用于 synchronized 同步代码块内

  synchronized 的内存语义

  与 volatile 不同

  进入 synchronized 块的内存语义是把在 synchronized 块内使用到的所有共享变量从栈内存中清空,这样就只能从堆内存只读取,保证了内存可见性。退出 synchronized 块的内存语义是把 synchronized 块内对共享变量的修改刷新到堆内存。

  仔细想想,这其实也是一个加锁和解锁的过程,保证共享变量修改的可见性。

  总结

  volatile 仅能保证单个共享变量内存的可见性,不能保证原子性。而 synchronized 既可保证同步块内所有共享变量的内存可见性,又能保证其操作的原子性。

  volatile 是一个轻量级的保证内存可见性的关键字,实际上并没有加锁。因此它的性能很高。

  synchronized 是一个重量级的锁,可以用在代码块、普通方法以及静态方法上。用在代码块时锁就是 synchronized(~) 内的对象,用在普通方法时锁就是this,用在静态方法时锁就是 this.getClass()

  synchronized 保证同步块内代码的原子性,因为要进行线程上下文切换,性能较低。不过优化过后性能也还可以。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
3月5日人民币对美元中间价调升117个基点

3月5日人民币对美元中间价调升117个基点

证券时报
2026-03-05 09:43:02
险遭19分大逆转!女篮险胜巴西却遭狂批:宫鲁鸣集训3个月在干啥

险遭19分大逆转!女篮险胜巴西却遭狂批:宫鲁鸣集训3个月在干啥

篮球快餐车
2026-03-04 22:13:11
委员建议,提高个税起征点至8000或1万

委员建议,提高个税起征点至8000或1万

中国新闻周刊
2026-03-04 14:49:13
女篮5分险胜!宫鲁鸣直接发火,3人满分,4人被打回原形,太差了

女篮5分险胜!宫鲁鸣直接发火,3人满分,4人被打回原形,太差了

生活新鲜市
2026-03-05 06:24:25
25% 库存 12 天打光,拦截弹 400 万一发,美国的高端防御,耗不起了

25% 库存 12 天打光,拦截弹 400 万一发,美国的高端防御,耗不起了

Ck的蜜糖
2026-03-04 21:04:20
美国务卿要“放蒋出笼”对付伊朗

美国务卿要“放蒋出笼”对付伊朗

远方青木
2026-03-05 00:13:22
沈伯洋祸害全家!家族海内外资产被冻结,面临破产;子女留学被拒

沈伯洋祸害全家!家族海内外资产被冻结,面临破产;子女留学被拒

可乐爱微笑
2026-01-09 19:45:04
1-0!阿森纳7分领跑却遭全英痛骂:丑陋夺冠能否终结22年等待?

1-0!阿森纳7分领跑却遭全英痛骂:丑陋夺冠能否终结22年等待?

落夜足球
2026-03-05 12:26:40
刚刚,库克掀桌!史上最便宜MacBook下到3999元,年轻人第一台苹果电脑?

刚刚,库克掀桌!史上最便宜MacBook下到3999元,年轻人第一台苹果电脑?

智东西
2026-03-05 00:29:46
马思纯官宣和张曼乐分手!谈分手原因太唏嘘,和欧豪在一起时不同

马思纯官宣和张曼乐分手!谈分手原因太唏嘘,和欧豪在一起时不同

古希腊掌管月桂的神
2026-03-05 10:44:23
19战16胜,黑马29分大胜东部第二!4号秀平乔丹神纪录+4换2淘到宝

19战16胜,黑马29分大胜东部第二!4号秀平乔丹神纪录+4换2淘到宝

锅子篮球
2026-03-05 12:30:34
北京门头沟区市监局回应“寿司郎吃出金枪鱼寄生虫卵”

北京门头沟区市监局回应“寿司郎吃出金枪鱼寄生虫卵”

界面新闻
2026-03-04 21:37:00
湖南中药学女大学生进山寻找草药视频走红,本人提醒:是药三分毒,切勿模仿

湖南中药学女大学生进山寻找草药视频走红,本人提醒:是药三分毒,切勿模仿

极目新闻
2026-03-04 21:43:49
轰21+7+7,老詹预定一项历史第一!湖人22战17胜2年1100万捡到宝

轰21+7+7,老詹预定一项历史第一!湖人22战17胜2年1100万捡到宝

锅子篮球
2026-03-04 15:15:07
国内将逐渐停止胃镜检查?做检查对身体有影响?医生告诉您真相

国内将逐渐停止胃镜检查?做检查对身体有影响?医生告诉您真相

小胡军事爱好
2026-03-04 10:19:16
当今社会十大傻:

当今社会十大傻:

超级数学建模
2026-03-04 13:01:38
欧洲天然气价格下跌7%

欧洲天然气价格下跌7%

每日经济新闻
2026-03-04 18:26:06
女单大满贯改打5盘3胜?萨巴伦卡、莱巴金娜想法大不同

女单大满贯改打5盘3胜?萨巴伦卡、莱巴金娜想法大不同

体育妞世界
2026-03-05 10:51:07
“玩不起!”浙江杭州,一男子开着自己花43万买的奥迪A6L

“玩不起!”浙江杭州,一男子开着自己花43万买的奥迪A6L

趣味萌宠的日常
2026-03-05 06:31:36
30岁小叔子和35岁嫂子去赶集,路过苞谷地,嫂子说这样一句话

30岁小叔子和35岁嫂子去赶集,路过苞谷地,嫂子说这样一句话

热心市民小黄
2026-03-04 08:12:16
2026-03-05 12:48:49
域之微科技
域之微科技
给大家分享最新的微科技资讯
8文章数 52258关注度
往期回顾 全部

科技要闻

阿里内部邮件回应:批准林俊旸辞职

头条要闻

媒体:若"委内瑞拉2.0"情景落空 白宫的经济叙事将崩塌

头条要闻

媒体:若"委内瑞拉2.0"情景落空 白宫的经济叙事将崩塌

体育要闻

2026年中超,为什么值得你多看一眼?

娱乐要闻

谢娜下场撕薛之谦,张杰前女友爆猛料

财经要闻

“十五五”开局之年,这么干!

汽车要闻

鸿蒙智行首款猎装车 尚界Z7/Z7T首发

态度原创

教育
游戏
健康
手机
数码

教育要闻

收藏:2026山东高中综评平台填写,家长评语!

《THE CUBE,SAVE US》3月18日开启Steam抢先体验

转头就晕的耳石症,能开车上班吗?

手机要闻

三星Galaxy A37/A57手机渲染图曝光

数码要闻

为了成为最便宜的Mac,苹果在MacBook Neo上做了哪些妥协?

无障碍浏览 进入关怀版