JMM模型

什么是JMM模型

JMM模型即Java内存模型,是一种规范,定义了在多线程环境下,变量的访问规则和线程之间通信的方式。它确保了在不同线程中共享的变量的一致性和可见性。
在这里插入图片描述

// 主内存
是所有线程共享的内存区域,所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问.
// 工作内存
是每个线程独有的内存区域,存储了线程使用的变量的副本。
线程对变量的操作(读取赋值等)必须在工作内存中进行:
1.首先要将变量从主内存拷贝的自己的工作内存空间 ->
2.然后对变量进行操作 ->
3.操作完成后再将变量写回主内存.
不能直接操作主内存中的变量,工作内存中存储着主内存中的变量副本拷贝.
// 线程间通信
因此不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成.正因为有这样的机制,所以存在可见性问题.

JMM与硬件内存架构的关系

// 主内存 <-> 物理内存(RAM)
主内存是所有线程共享的内存区域,存储了变量的实际值。
在硬件层面,主内存通常对应于物理内存(RAM),是计算机中存储数据和程序的主要地方。
// 工作内存 <-> 寄存器、高速缓存、线程栈
在硬件层面,工作内存的对应关系更为复杂,它涵盖了寄存器、高速缓存(L1L2L3缓存等),以及线程栈(Thread Stack1.寄存器
寄存器是位于CPU内部的存储单元,直接与CPU核心交互。变量在工作内存中可能存在于寄存器中,以提高访问速度。

2.高速缓存
CPU核心通常具有多级缓存,分为L1L2L3等级别。这些缓存用于存储频繁访问的数据,也可能包含工作内存中的变量的副本。

3.线程栈
每个线程都有自己的线程栈,用于存储局部变量和方法调用的信息。线程栈中的数据也可以看作是线程的工作内存的一部分。

在这里插入图片描述

并发编程三大特性

// 原子性
原子性指的是一个操作是不可中断的,即使是在多线程环境下,一个操作一旦开始就不会被其他线程影响。
通常使用 synchronizedLockvolatile不保证原子性)

// 可见性
当一个线程修改了某个共享变量的值,其他线程是否能够马上得知这个修改的值。
volatile可以解决可见性(保证能否及时看到)

// 有序性
有序性是指对于单线程的执行代码,我们总是认为代码的执行是按顺序依次执行的,但对于多线程环境,则可能出现乱序现象,因为程序编译成机器码指令后可能会出现指令重排现象,重排后的指令与原指令的顺序未必一致。
(volatile可以防止指令重排)

内存交互操作

关于主内存和工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存,如何从工作内存同步到主内存之间的实现,JMM定义了以下8种操作完成。

// lock(锁定)
作用与主内存的变量,把一个变量标记为一条线程独占状态。
// unlock(解锁)
作用与主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
// read(读取)
将主内存的数据拷贝一份,便于随后的load使用
// load(载入)
将read拷贝的数据加载到工作内存中
// use(使用)
将工作内存中的数据变量给执行引擎进行逻辑修改
// assign(赋值)
将执行引擎修改的值写回线程的工作内存
// store(存储)
将工作内存的值拷贝一份出来
// write(写入)
将store出来的值写回主内存

// 举例
假设线程A要修改主内存中的变量a = 0 -> a=1
1.首先read()将主内存的变量a=0拷贝一份
2.通过load()加载到线程A的工作内存,
3.然后use()将工作内存中a=0交给执行引擎,执行引擎将a=0修改为a=1
4.assign()将a=1写回工作内存,
5.store()将工作内存中的a=1拷贝一份出来
6.write()将a=1写回主内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值