不再迷惑的Java内存模型

本文深入探讨Java内存模型,解释其如何解决多线程环境下的缓存一致性与指令重排序问题,确保并发场景下的原子性、可见性和有序性。

一直以来,java内存模型都是让人很迷惑的东西,很多书籍,博客都有对它的相关介绍,很多人读完后,还是搞不清楚。而且这个东西和JVM的内存结构又很容易混淆,很多博客讲解内存模型都会当成JVM的内存结构去讲,甚至我身边有着好几年java工作经验的人,都搞不明白,说一些堆,虚拟机栈啥的。所以呢,今天就和读者一起来探究java内存模型到底是什么东西。这个模型是干嘛用的。

一说到模型,我相信很多人脑海中就会想象出一个具体的模型画面出来,由什么样的结构组成啊。但是,java内存模型却并不是这样的,所以才让很多的java学习者感到难以理解。在介绍Java内存模型之前,先说一下内存模型这个东西,在《深入理解Java虚拟机》中介绍 这是在特定的操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。怎么样,这个解释是不是很让人懵逼。

内存模型,实际上这是一个跟计算机硬件有关的概念。计算机在执行程序时,每条指令都是由CPU去执行的。在执行的时候,数据是存放在主存中,也就是计算机的物理内存,每次要将数据从主存读取到CPU中,再去执行,把执行后的结果再写回到内存中。但是随着CPU的执行速度越来越快,从内存中读取和写入数据的速度和CPU的执行速度相比,差距就越来越大,这样就导致了CPU效率低下,每次不得不耗费很多时间来等待数据的读取和写入。

后来,人们在CPU和内存之间加入了高速缓存,现在的CPU中已经包含了高速缓存。缓存就是保存一份数据的拷贝,特点就是速度快,内存小,而且很贵。这样以后程序执行就变成了这个样子:程序运行时,先将需要的数据从主存中拷贝一份到高速缓存,CPU进行计算可以直接从它的高速缓存中读取和写入数据,再将高速缓存中的数据刷新到主内存中。在后来计算机从单核CPU发展到多核CPU,也开始支持多线程。这样就会出现缓存不一致的问题。我们来看一下,这个问题是什么,当多个线程在不同的核心上分别执行,每个核心都会在各自的缓存中保留一份共享内存的副本,这样由于多核时可以并行的,可能会出现多个线程同时对各自的缓存进行写操作,这样各自的缓存之间的数据就会出现不一致的情况。举个例子:一家由多个合伙人创办的公司,合伙人A觉得员工小王天天偷懒,溜须拍马,打算辞退他,就让自己的秘书去办这件事,合伙人B觉得员工小王说话做事有一套,打算给他升职,也让自己的秘书去办这件事,结果,A的秘书办事比较快,立马就通知人事把小王开了,A就已经知道了小王被开除,此时,B还不知道小王被开,B的秘书也去办,这样就出了问题。

这种基于高速缓存的存储交互很好地解决了CPU与内存的速度矛盾,但是它引来了一个新的问题:缓存一致性。为了解决这个问题,需要各个处理器访问缓存时都要遵循一些协议,在读写时根据协议来进行操作,这类协议有MSI,MESI,Synapse等。除了这种情况,还有一种硬件问题也比较重要,那就是为了使处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果是一致的。这就是指令重排序优化。

上面所提到的缓存一致性,和指令重排序问题都是随着硬件的不断升级导致的,有什么办法能够解决这些问题呢。在这里就引入了内存模型这个概念,就是为了保证共享内存的正确性,定义了共享内存中多线程读写操作行为的规范。那么什么是Java内存模型呢,在《深入理解Java虚拟机》中是这样介绍的,Java内存模型是可以屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致内存访问效果这样一种规范。

Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量,不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存去完成。它们之间的交互关系如图所示:

在主内存与工作内存交互的细节上,java内存模型定义了以下8种操作来完成。这8种操作都是原子的。分别是lock(锁定),unlock(解锁),read(读取),load(载入),use(使用),assign(赋值),store(存储),write(写入)。如果要把一个变量从主内存复制到工作内存,那就要顺序执行read和load操作,如果要把变量从工作内存同步到主内存,就要顺寻执行store和write操作,同时java内存模型还规定了在执行这8种基本操作需要满足的规则,这里我就不再详述了,可以去看一下《深入理解Java虚拟机》。

另外,Java提供了一系列和并发处理相关的关键字,比如volatile,synchronized,final,concurrent包,这些关键字实际上就是java内存模型封装了底层的实现提供给开发者使用,从而不需要关心底层编译器优化,缓存一致性等问题,保证并发场景中的原子性,可见性,有序性。这些关键字的介绍,网上都有很多相关资料,读者可以自行去查看,

下面来介绍一下原子性,可见性,有序性这三个特性。

原子性:这个大家应该都很好理解,就是保证一个或一组操作是不可中断的,要么完成,要么不发生。在Java中可以使用synchronized关键字来保证方法或代码块的操作是原子性的。

可见性:可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改,volatile,synchronized,final都可以实现可见性。

有序性:就是程序执行的顺序按照代码的先后顺序去执行。java内存模型允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。java提供了volatile,synchronized这两个关键字来保证线程之间操作的有序性。

如果Java内存模型中所有的有序性都仅仅靠volatile和synchronized来完成,那么是不是很繁琐呀,实际上,Java语言里有一个先行发生(happens-before)的原则。这个原则是判断数据是否存在竞争,线程是否安全的重要依据。先行发生是Java内存模型中定义的两项操作之间的偏序关系,如果说操作A先行发生于操作B,那么操作A产生的影响能被操作B观察到。这个影响包括了修改了内存中共享变量的值,发送了消息,调用了方法等。

总结一下:Java内存模型是一种规范,目的是解决多线程通信之间造成的缓存一致性,编译器和处理器的指令重排序所带来的问题,从而保证并发场景下的原子性,可见性,有序性。

内容概要:本文设计了一种基于PLC的全自动洗衣机控制系统内容概要:本文设计了一种,采用三菱FX基于PLC的全自动洗衣机控制系统,采用3U-32MT型PLC作为三菱FX3U核心控制器,替代传统继-32MT电器控制方式,提升了型PLC作为系统的稳定性与自动化核心控制器,替代水平。系统具备传统继电器控制方式高/低水,实现洗衣机工作位选择、柔和过程的自动化控制/标准洗衣模式切换。系统具备高、暂停加衣、低水位选择、手动脱水及和柔和、标准两种蜂鸣提示等功能洗衣模式,支持,通过GX Works2软件编写梯形图程序,实现进洗衣过程中暂停添加水、洗涤、排水衣物,并增加了手动脱水功能和、脱水等工序蜂鸣器提示的自动循环控制功能,提升了使用的,并引入MCGS组便捷性与灵活性态软件实现人机交互界面监控。控制系统通过GX。硬件设计包括 Works2软件进行主电路、PLC接梯形图编程线与关键元,完成了启动、进水器件选型,软件、正反转洗涤部分完成I/O分配、排水、脱、逻辑流程规划水等工序的逻辑及各功能模块梯设计,并实现了大形图编程。循环与小循环的嵌; 适合人群:自动化套控制流程。此外、电气工程及相关,还利用MCGS组态软件构建专业本科学生,具备PL了人机交互C基础知识和梯界面,实现对洗衣机形图编程能力的运行状态的监控与操作。整体设计涵盖了初级工程技术人员。硬件选型、; 使用场景及目标:I/O分配、电路接线、程序逻辑设计及组①掌握PLC在态监控等多个方面家电自动化控制中的应用方法;②学习,体现了PLC在工业自动化控制中的高效全自动洗衣机控制系统的性与可靠性。;软硬件设计流程 适合人群:电气;③实践工程、自动化及相关MCGS组态软件与PLC的专业的本科生、初级通信与联调工程技术人员以及从事;④完成PLC控制系统开发毕业设计或工业的学习者;具备控制类项目开发参考一定PLC基础知识。; 阅读和梯形图建议:建议结合三菱编程能力的人员GX Works2仿真更为适宜。; 使用场景及目标:①应用于环境与MCGS组态平台进行程序高校毕业设计或调试与运行验证课程项目,帮助学生掌握PLC控制系统的设计,重点关注I/O分配逻辑、梯形图与实现方法;②为工业自动化领域互锁机制及循环控制结构的设计中类似家电控制系统的开发提供参考方案;③思路,深入理解PL通过实际案例理解C在实际工程项目PLC在电机中的应用全过程。控制、时间循环、互锁保护、手动干预等方面的应用逻辑。; 阅读建议:建议结合三菱GX Works2编程软件和MCGS组态软件同步实践,重点理解梯形图程序中各环节的时序逻辑与互锁机制,关注I/O分配与硬件接线的对应关系,并尝试在仿真环境中调试程序以加深对全自动洗衣机控制流程的理解
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值