JUC-08-JMM+Volatile

本文详细介绍了Java内存模型(JMM)的概念及其在多线程环境中的作用,并深入探讨了Volatile关键字如何确保变量的可见性和禁止指令重排,帮助理解并发编程中的关键问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JMM

Volatile是java虚拟机提供轻量级的同步机制
1、保证可见性
2、不保证原子性
3、禁止指令重排

什么是JMM
java内存模型,不存在的东西,概念!约定!

关于JMM的一些同步的约定

1、线程解锁前,必须把共享变量立刻刷回主存
2、线程加锁前,必须读取主存中的最新值到工作内存中
3、加锁和解锁是同一把锁

在这里插入图片描述
在这里插入图片描述

。lock(锁定),作用于主内存中的变量,把变量标识为线程独占的状态。
。read(读取),作用于主内存的变量,把变量的值从主内存传输到线程的工作内存中,以便下一步的load操作使用。
。load(加载),作用于工作内存的变量,把read操作主存的变量放入到工作内存的变量副本中。
。use(使用),作用于工作内存的变量,把工作内存中的变量传输到执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作。
。assign(赋值),作用于工作内存的变量,它把一个从执行引擎中接受到的值赋值给工作内存的变量副本中,每当虚拟机遇到一个给变量赋值的字节码指令时将会执行这个操作。
。store(存储),作用于工作内存的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的write使用。
。write(写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。
。unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。

JMM对8种内存交互操作制定的规则:
。>不允许read、load、store、write操作之一单独出现,也就是read操作后必须load,store操作后必须write。
。不允许线程丢弃他最近的assign操作,即工作内存中的变量数据改变了之后,必须告知主存。
。不允许线程将没有assign的数据从工作内存同步到主内存。
。一个新的变量必须在主内存中诞生,不允许工作内存直接使用一个未被初始化的变量。就是对变量实施use、store操作之前,必须经过load和assign操作。
。一个变量同一时间只能有一个线程对其进行lock操作。多次lock之后,必须执行相同次数unlock才可以解锁。
。如果对一个变量进行lock操作,会清空所有工作内存中此变量的值。在执行引擎使用这个变量前,必须重新load或assign操作初始化变量的值。
。如果一个变量没有被lock,就不能对其进行unlock操作。也不能unlock一个被其他线程锁住的变量。
。一个线程对一个变量进行unlock操作之前,必须先把此变量同步回主内存。

问题:程序不知道主内存的值已经被修改过了

Volatile

1、保证可见性

在这里插入图片描述

2、不保证原子性:不可分割
线程A在执行任务的时候,不能被打扰的,也不能被分割,要么同时成功,要么同时失败

在这里插入图片描述
如果不加lock和synchronized,怎么保证原子性
在这里插入图片描述

使用原子类,解决原子性问题

这些类的底层都直接和操作系统挂钩!在内存中修改值!Unsafe类是一个很特殊的存在!

指令重排

什么是指令重排:写的程序,计算机并不知道按照你写的那样去执行的

volatile可以避免指令重排

内存屏障。CPU指令。作用:
1、保证特定的操作的执行顺序
2、可以保证某些变量的内存可见性(利用这些特性volatile实现了可见性)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

协奏曲❤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值