Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >多线程的共享变量的内存不可见性

多线程的共享变量的内存不可见性

作者头像
Vincent-yuan
发布于 2021-07-16 03:45:28
发布于 2021-07-16 03:45:28
76100
代码可运行
举报
文章被收录于专栏:Vincent-yuanVincent-yuan
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
线程的开销 :
  • 线程的创建和销毁
  • 线程的上下文切换和调度
  • 线程的同步
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
多线程的内存模型: 线程独有的工作内存(线程缓存用于提高效率)---------所有线程共享的主内存

线程读取在主内存的成员变量(即共享变量)的过程:

  1. 线程的工作内存会去读取主内存的成员变量并保存副本
  2. 线程在工作内存中修改副本
  3. 将修改后的副本的值推送给主空间并改写主空间该成员变量的值
  4. 主空间成员变量修改后的值将不会主动推送给其他线程, 这就造成了线程的工作内存的共享变量的不同步
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
问题: 各个线程的工作内存不可见
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  即 A线程先读取共享变量a, B线程修改了共享变量a后为a`,推送给主内存并改写, 主内存不会推送给A线程,AB的变量会不同步

解决办法

  • synchroized可以同步值
  • volatile关键字 会使得主内存的共享变量每经过一次改变都会推送给其他的线程, 其他线程会修改其副本

同步值之synchronized和volatile的区别 相同点:   synchronized 和 volatile都能用来同步共享变量 不同点:   1. volatile是轻量级的同步策略, 可以修饰基本类型的变量,如int, synchronized是重量级的同步策略,基于对象的同步锁   2. volatile不具备互斥性, 一个线程访问共享变量 , 其他线程也可以访问共享变量     synchronized是互斥锁, 具备互斥性, 在被锁的代码块上只能有一个线程访问共享变量   3. volatile不能保证变量的原子性, 即一组对共享变量的操作不具备事务(要么全部完成,要么全部不完成) 如 i++/i-- 即一个线程在进行一组操作中还没完成时, 其他线程也能进入这组操作对共享变量进行修改 而 synchronized则能保证一组对共享变量操作的原子性, 即这组操作全部完成,才能进行下一轮操作 即在被锁的代码块中只能允许一个线程去执行这组操作, 其他需要执行这组操作的线程会进入阻塞状态,等待其完成 总结:

主内存    工作内存 共享变量   副本 工作内存中会主动去拉取主内存的共享变量并创建其副本 工作内存中的副本修改后会推送给主内存改写共享变量 volatile 会使得主内存修改后的共享变量推送其他线程 内存不可见的本质 : 线程之间有互相独立的缓存区, 当多个线程对共享数据进行操作时, 其操作彼此不可见 可以直接理解: 使用volatile之后该共享该变量线程不在工作内存缓存其副本, 所有线程对该变量的操作全是在主内存中完成 即不在存在操作的不可见,所有线程的操作的变量是位于主内存的变量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.cnblogs.com/huangleshu/p/10026222.html
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验