深入理解volatile关键字

故事要从盘古开天辟地的时候说起,不好意思,走错片场了…

想要深入理解volatile就必须从Java虚拟机层面去理解,所以,在介绍volatile关键字之前就要从硬件谈起。

硬件的效率与一致性

由于计算机的读写速度与其运算速度差距十分巨大,所以,计算机上都会加一层读写速度尽可能接近处理器运算速度的高速缓存(cache)来作为内存与处理器之间的缓冲:意思就是将需要用到的数据放到缓存中,让运算快速进行。当运算结束后将数据从缓存同步会内存。

那么,问题来了,挖掘机技术哪家强?第二个问题:缓存一致性

在多处理器中,每个处理器都有自己的高速缓存,而他们共享同一主存,多个处理器运算涉及同一块主存,需要一种协议去保障数据一致性,这类协议有MSI、MESI、MOSI及Dragon Protocol等。Java虚拟机内存模型中定义的内存访问操作与硬件的缓存访问操作是具有可比性的。

为了使处理器内部运算单元充分利用,处理器会对输入代码进行乱起执行优化,处理器会在计算之后将对乱序执行的代码进行重组,确保其准确性。与去处理器乱序执行的优化,Java虚拟机对应的即时编译器中也有类似的指令重排优化。

在这里插入图片描述

Java内存模型

Java内存模型主要目的是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量包括实例字段,静态字段和构成数组对象的元素,但是不包括局部变量和方法参数,后者是私有的,不会被共享。

Java内存模型规定了所有变量都存储在内存中,每条线程都有自己的工作内存(与处理器的高速缓存类似),线程的工作内存中保存了该线程使用到的变量是主内存副本拷贝,线程对所有变量的操作(读取赋值)都必须在工作内存中进行,而不能直接读写主内存的变量。不同线程之间无法直接访问对方工作内存中的变量,线程间变量的传递都必须依靠主内存来完成,线程,主存和工作内存间的交互关系和硬件的类似。

在这里插入图片描述

内存之间的交互操作

关于主存与内存之间的交互操作,即一个变量如何从主存拷贝到工作内存,如何从工作内存同步到主存之间的细节,Java内存模型定义了以下八大操作来完成:

  • lock(锁定)
  • unlock(解锁)
  • read(读取)
  • load(载入)
  • use(使用)
  • assign(赋值)
  • store(存储)
  • write(写入)

Java内存模型围绕着原子性,可见性,有序性来建立的

好,经过前面的铺垫,终于可以要说到今天猪脚了

我们来举例说明

现在有一个静态变量

static int s= 0;

线程A执行以下代码: s = 3;

在JMM中发生的事情为:

1.主内存中加载s变量

2.通过工作内存读写到线程A中 得到 S = 0

3.执行线程A代码,将线程修改的变量同步到主内存中

在这里插入图片描述

如果这时候来了一个线程B:执行以下代码:System.out.println(“s=” + s);

结果不一定为3,还有可能为0

为0的情况是因为工作内存所更新的变量并不会立即同步到主内存,所以虽然线程A在工作内存当中已经把变量s的值更新成3,但是线程B从主内存得到的变量s的值仍然是0,从而输出 s=0

那么如何解决这个问题呢?

虽然我们可以使用synchronized来确保线程安全,但是对程序性能影响太大了,有一种轻量级的解决办法,那就是使用我们的的猪脚。

volatile关键字中最重要的特性就是保住了被其修饰的变量对所有线程可见性

这里的可见性是什么意思呢?当一个线程修改了变量的值,新的值会立刻同步到主内存当中。而其他线程读取这个变量的时候,也会从主内存中拉取最新的变量值。

为什么volatile关键字可以有这样的特性?这得益于java语言的先行发生原则(happens-before)。

先行发生原则是两个事件的结果之间的关系,如果一个事件发生在另一个事件之前,结果必须反映,即使这些事件实际上是乱序执行的(通常是优化程序流程)。

对于一个volatile变量的写操作先行发生于后面对这个变量的读操作。

虽然volatile可以保证变量的可见性,但不能保证其原子性

何为指令重排?

指令重排是指JVM在编译Java代码的时候,或者CPU在执行JVM字节码的时候,对现有的指令顺序进行重新排序。

指令重排的目的是为了在不改变程序执行结果的前提下,优化程序的运行效率。需要注意的是,这里所说的不改变执行结果,指的是不改变单线程下的程序执行结果

然而,指令重排是一把双刃剑,虽然优化了程序的执行效率,但是在某些情况下,会影响到多线程的执行结果。

那么,指令重排怎么解决呢?可以通过内存屏障来解决

什么是内存屏障?

内存屏障(Memory Barrier)是一种CPU指令

内存屏障也称为内存栅栏或栅栏指令,是一种屏障指令,它使CPU或编译器对屏障指令之前和之后发出的内存操作执行一个排序约束。 这通常意味着在屏障之前发布的操作被保证在屏障之后发布的操作之前执行

内存屏障分为四种:

LoadLoad屏障:

抽象场景:Load1; LoadLoad; Load2

Load1 和 Load2 代表两条读取指令。在Load2要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

StoreStore屏障:

抽象场景:Store1; StoreStore; Store2

Store1 和 Store2代表两条写入指令。在Store2写入执行前,保证Store1的写入操作对其它处理器可见

LoadStore屏障:

抽象场景:Load1; LoadStore; Store2

在Store2被写入前,保证Load1要读取的数据被读取完毕。

StoreLoad屏障

抽象场景:Store1;StoreLoad;Load2

在Load2读取之前,保证Store1的写入对所有处理器可见,StoreLoad屏障的开销是四中屏障中最大的

volatile做了什么?

在一个变量被volatile修饰后,JVM会为我们做两件事:

1.在每个volatile写操作前插入StoreStore屏障,在写操作后插入StoreLoad屏障。

2.在每个volatile读操作前插入LoadLoad屏障,在读操作后插入LoadStore屏障。

所以其防止了指令重排

总结一下volatile关键字

volatile特性之一:

保证变量在线程之间的可见性。可见性的保证是基于CPU的内存屏障指令,被JSR-133抽象为happens-before原则。

volatile特性之二:

阻止编译时和运行时的指令重排。编译时JVM编译器遵循内存屏障的约束,运行时依靠CPU屏障指令来阻止重排。

文章参考https://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html
文章参考https://blog.youkuaiyun.com/bjweimengshu/article/details/78860580

资源下载链接为: https://pan.quark.cn/s/72147cbc453d 在当今信息化时代,高校社团管理的高效性与便捷性至关重要。基于 Spring Boot 开发的社团管理系统,致力于打造一个功能全面、操作便捷且安全可靠的平台,以满足高校社团的日常运营需求。本文将深入剖析该系统的架构设计、核心功能以及实现原理。 Spring Boot 以其轻量级和快速开发的特性,成为众多企业级应用的首选框架。本社团管理系统采用 Spring Boot 搭建,并遵循 RESTful API 设计原则,构建出一个松耦合、模块化的架构。借助 Spring Boot 的自动配置功能,项目初始化工作得以大幅简化,使开发者能够更加专注于业务逻辑的开发。 权限管理是系统安全的关键环节。本系统引入多级权限控制机制,确保不同角色(如管理员、普通成员等)能够访问其对应的系统功能。通常会借助 Spring Security 或 Apache Shiro 等安全框架,通过角色、权限与资源的映射关系,实现对用户操作的精细化管理。 为了提升用户体验和提高信息传递效率,系统集成了短信接口。在用户注册、密码找回、活动报名等关键操作环节,通过短信验证码进行验证。这需要与第三方短信服务提供商(如阿里云、腾讯云等)进行对接,利用其 SDK 实现短信的发送与接收功能。 会员管理:涵盖会员注册、登录、信息修改及权限分配等功能,方便社团成员进行自我管理。 活动管理:支持活动的创建、审批、报名以及评价等全流程管理,便于社团组织各类活动。 场地管理:实现场地的预定、审批和使用记录管理,确保资源的有效分配。 会议管理:提供会议安排、通知以及签到等功能,提升会议组织效率。 社团管理:包括社团的创建、修改、解散以及社团成员管理等功能。 消息通知:能够实时推送系统消息,保障信息的及时传达。 文件下发:支持文件的上传与下载,方便
资源下载链接为: https://pan.quark.cn/s/79a048d3db20 格陵兰多媒体教学系统V7.0(专业版)-7.0.016是一款专为局域网有线网络环境设计的电子教室机房教学软件,致力于提升教学效率与互动性,助力教师高效管理与掌控课堂。该专业版系统具备丰富功能,满足现代教育需求。 其核心功能之一是广播教学。教师可将自身电脑屏幕内容实时同步至所有学生电脑,全班同学能同步查看相同教学内容,无论是演示课件、播放视频还是操作软件,都能实现统一教学节奏,从而提升教学效率。 个性化小组教学功能则允许教师针对不同学生或小组开展针对性教学。教师可选择部分学生进行单独讲解或组织分组讨论,既能兼顾每个学生的学习进度,又能激发学生间的合作与竞争,增强学习的趣味性和深度。 此外,教学测验功能便于教师进行课堂评估。教师可设计并发布在线测验,实时收集学生答题情况,快速掌握学生对课程内容的理解程度,及时调整教学策略。这种即时反馈机制有助于优化教学过程,保障学生学习效果。 在远程集控管理方面,该系统为教师提供了强大工具。教师可远程操控学生电脑,进行屏幕监控,防止学生课堂分心或进行无关活动,还能统一管理学生电脑设置,如禁用特定程序或网站,维护课堂秩序。 系统中还包含Searcher.exe,这可能是一款搜索工具,方便教师和学生快速查找课堂所需教学资源。而Readme.txt通常记录了软件的安装指南、更新日志或使用注意事项,是初次使用者获取软件信息的重要途径。 格陵兰多媒体教学系统V7.0(专业版)融合了现代信息技术与教育实践,提供了一站式教学解决方案。它使教师能够更灵活、高效地开展教学活动,为学生创造更优质的学习体验。凭借其多元化功能,该系统不仅提高了教学效率,还促进了师生互动交流,契合信息化时代教育需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值