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

2022-10-27 16:43:47 浏览数 (1)

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

其实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修饰的变量,执行引擎会一直从工作内存中读取数据。所以变量就不能共享啦。

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

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

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

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

现在的缓存锁定机制机会都是缓存一致性协议(MESI协议)
java

0 人点赞