前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >变量如何在多线程下独善其身

变量如何在多线程下独善其身

作者头像
姜同学
发布2022-10-27 16:43:47
2340
发布2022-10-27 16:43:47
举报
文章被收录于专栏:姜同学

多个线程见是怎么共享数据的

其实java的内存模型是基于cpu的多级缓存架构设计的并且不同的线程 之间默认是不可共享变量的。如果想要实现变量在线程之间的可见性可 已使用Volatile关键字修饰该变量。

为什么线程之间的变量不可以共享

解决这个问题之前要先了解一下Java内存模型8大原子操作
1.lock(锁定)

作用于主内存的变量,把一个变量标记为一条线程独占状态

2.unlock(解锁)

作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放之后 的变量才可以被其他线程锁定

3.read(读取)

把一个变量值从主内存传输到线程的工作内存中,以便随后的动作 使用

4.load(载入)

它把read操作从主存中得到的变量加载到线程工作内存的变量副本中 变量副本是线程独享的。

5.use(使用)

把工作内存中的变量值传递到执行引擎

6.assign(赋值)

它把执行引擎接收到的值赋给工作内存的变量

7.store(存储)

把工作内存中的值传入到主内存中,以便随后的write的操作

8.write(写入)

把store操作从工作内存中的一个变量的值传送到主内存的变量中

ps:不是使用Volatile修饰的变量,执行引擎会一直从工作内存中读取数据。所以变量就不能共享啦。

JMM原子操作
JMM原子操作

为什么使用Volatile修饰的变量可以实现线程之间的共享

底层实现:JAVA编程思想里有这么一句话所有编程语言都提供抽象机制。 从某种程度上来说,问题的复杂度直接取决于抽象的类型和质量。这里 的“类型”意思是:抽象的内容是什么?汇编语言是对底层机器的轻微抽 象。接着出现的“命令式”语言(如 FORTRAN,BASIC 和 C)是对汇编语 言的抽象。

所以通过汇编lock前缀指令触发底层缓存机制(缓存一致性协议&总线锁) 例0如0触发MESI协议,lock指令会触发锁定变量缓存行区域并写回主内存, 这个操作称为“缓存锁定”

代码语言:javascript
复制
比较老的cpu使用的是总线锁机制,何为总线锁?
当有线程正在使用Volatile修饰的变量,这时主存
直接被锁定,就算你想访问阿猫阿狗都不可以,是
非常影响效率的。

现在的缓存锁定机制机会都是缓存一致性协议(MESI协议)
java
MESI
MESI
MESI
MESI
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-06T,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多个线程见是怎么共享数据的
  • 为什么线程之间的变量不可以共享
    • 解决这个问题之前要先了解一下Java内存模型8大原子操作
    • 为什么使用Volatile修饰的变量可以实现线程之间的共享
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档