Java内存模型

本文深入解析Java内存模型(JMM),包括其概念、主内存与工作内存的区别,以及原子性、有序性和可见性的核心特性。此外,还介绍了如何通过synchronized、volatile及Happens-before原则确保线程间的正确交互。

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

;Java内存模型(JMM):首先JMM是一个抽象的额概念,它并不不存在(Java内存区域是两个不同的概念);JMM描述的是一组规则和规范,这种规范描述的是程序运行中各个变量的访问方式;由于JVM的实体是线程,每个线程在JVM中运行时,JVM都会为其创建一个工作内存,该工作内存是属于线程私有的;Java内存模型规定,所有的变量都存放在主内存中,主内存是各个线程间共享的,但线程对变量的操作必须放在工作内存中;首先从主内存中拷贝变量的各自额工作内存中然后在工作内存中进行变量的相关操作,之后在将工作内存中的变量副本写入到主内存中,线程不能直接对主内存中的变量进行操作;

  1. 主内存:主要存放的是Java实例对象,所有线程创建的额实例对象都存放在这里,不管该实例对象是成员变量还是局部变量;也会包括共享的类信息,常量,静态变量等;由于这是线程之间的共享的区域,所以多个线程进行操作时可能会出现线程安全问题;
  2. 工作内存:主要存储当前方法的本地变量信息(工作内存中存放的是主内存中的变量副本)每个线程只能访问自己的工作内存,即线程中的额本地变量定义其它线程是不可见的;由于工作内存是每个线程间私有的,所以线程间是不会互相方法对方的工作内存,这也就使得不会产生线程安全问题;

;Java内存模型中的原子性,有序性,可见性;

  1. 原子性:即一个操作是不可能中断的;例如对于一个静态变量X,有两个线程同时执行它,A线程赋值为X=1;B线程赋值为X=2;不管线程如何运行,X的结果要么是1,要么是2;线程A和线程B之间的操作是不受影响的,这就是原子性操作,不可被中断的特点;(对于方法级或者代码块级别的原子性操作可以使用synchronize和重入锁ReentrantLock来保证)
  2. 有序性:对于单线程中,在本线程内所有的操作都是有序的,但在多线程下,在一个线程观察另一个线程,所有操作都是无序的,无序是因为发生了指令重排;(而工作内存与住主内存发生的同步延迟导致的可见性问题,可以使用synchronized关键字和volatile关键字解决;对于指令重排的可见性和有序性问题可以使用volatile关键字解决)
  3. 可见性:指一个线程对共享变量修改后,其他线程是可以立马可见的;对于串行程序来说,可见性是不存在的,当线程修改了这个变量的值,依次执行后面的操作,紧接着就可以读取到该变量修改后的值;但是对于多线程程序中,由于线程对共享变量的操作都是变量的值拷贝一份到各自的工作内存中进行相关的操作,然后在写入到主内存中,其他线程才可见,假如A线程对共享变量X操作赋值为1;在该变量还未写入到主内存中时,线程B又对该共享变量进行操作,由于线程间的工作内存不是共享的,所以AX的修改对线程B来说就不可见;这种工作内存与主内存同步延迟现象就造成了可见性问题;

,解决方案:

  1. 针对原子性: 除了JVM自身提供的对基本数据类型读写操作的原子性外,对于方法级别或者代码块级别的原子性操作,可以使用synchronized关键字或者重入锁(ReentrantLock)保证程序执行的原子性;
  2. 针对可见性: 而工作内存与主内存同步延迟现象导致的可见性问题,可以使用synchronized关键字或者volatile关键字解决,它们都可以使一个线程修改后的变量立即对其他线程可见。
  3. 针对有序性: 对于指令重排导致的可见性问题和有序性问题,则可以利用volatile关键字解决,

#Happens-before(先行发生原则):除了上述使用Synchronized关键字和volatile来解决线程执行中存在的原子性,有序性,可见性外,在保证效率的前提下,还可以使用先行发生原则”,使用该原则可以辅助保证程序执行的原子性,可见性,有序性; 它是判断数据是否存在竞争、线程是否安全的依据,happens-before 原则内容如下:

  1. 单一线程原则:在一个程序内,在程序前面的操作先行发生于后面的操作,也就是按照代码顺序执行;
  2. 锁规则:解锁(unlock)操作必然发生在后续同一个锁加锁(locl)之前,也就是说对于同一个锁解锁后,再加锁,那么加锁必须发生在解锁动作之后(同一个锁);(换言之:一个unlock操作先行发生于后面对同一个锁的lock操作)
  3. Volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作;这也就保证了volatile变量的可见性;
  4. 线程启动规则:Thread对象的start()方法调用先行发生于此线程的每一个动作, 即如果线程A在执行线程B的start方法之前修改了共享变量的值,那么当线程B执行start方法时,线程A对共享变量的修改对线程B可见;
  5. 传递性:如果A操作先行与B操作,B操作先行于C操作,那么A操作先行于C操作;
  6. 线程终止规则:线程所有的操作先行于线程的终结操作; (Join方法先行发生于Thread对象的结束)Thread.join()方法的作用是等待当前执行的线程终止。假设在线程B终止之前,修改了共享变量,线程A从线程B的join方法成功返回后,线程B对共享变量的修改将对线程A可见。
  7. 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生;
  8. 对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始;

以上8条原则,可以在不适用(synchronized|volatile)的情况下线程在执行时的原子性,有序性,可见性;

:Volatile关键字:

使用volatile修饰的变量具有以下两个特性:

  1. 修饰的变量具有可见性,当一个线程修改了这个变量的值,volatile保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新;
  2. 修饰的变量不允许线程内部缓存和重排序;
标题“51单片机通过MPU6050-DMP获取姿态角例程”解析 “51单片机通过MPU6050-DMP获取姿态角例程”是一个基于51系列单片机(一种常见的8位微控制器)的程序示例,用于读取MPU6050传感器的数据,并通过其内置的数字运动处理器(DMP)计算设备的姿态角(如倾斜角度、旋转角度等)。MPU6050是一款集成三轴加速度计和三轴陀螺仪的六自由度传感器,广泛应用于运动控制和姿态检测领域。该例程利用MPU6050的DMP功能,由DMP处理复杂的运动学算法,例如姿态融合,将加速度计和陀螺仪的数据进行整合,从而提供稳定且实时的姿态估计,减轻主控MCU的计算负担。最终,姿态角数据通过LCD1602显示屏以字符形式可视化展示,为用户提供直观的反馈。 从标签“51单片机 6050”可知,该项目主要涉及51单片机和MPU6050传感器这两个关键硬件组件。51单片机基于8051内核,因编程简单、成本低而被广泛应用;MPU6050作为惯性测量单元(IMU),可测量设备的线性和角速度。文件名“51-DMP-NET”可能表示这是一个51单片机及DMP相关的网络资源或代码库,其中可能包含C语言等适合51单片机的编程语言的源代码、配置文件、用户手册、示例程序,以及可能的调试工具或IDE项目文件。 实现该项目需以下步骤:首先是硬件连接,将51单片机MPU6050通过I2C接口正确连接,同时将LCD1602连接到51单片机的串行数据线和控制线上;接着是初始化设置,配置51单片机的I/O端口,初始化I2C通信协议,设置MPU6050的工作模式和数据输出速率;然后是DMP配置,启用MPU6050的DMP功能,加载预编译的DMP固件,并设置DMP输出数据的中断;之后是数据读取,通过中断服务程序从DMP接收姿态角数据,数据通常以四元数或欧拉角形式呈现;再接着是数据显示,将姿态角数据转换为可读的度数格
MathorCup高校数学建模挑战赛是一项旨在提升学生数学应用、创新和团队协作能力的年度竞赛。参赛团队需在规定时间内解决实际问题,运用数学建模方法进行分析并提出解决方案。2021年第十一届比赛的D题就是一个典型例子。 MATLAB是解决这类问题的常用工具。它是一款强大的数值计算和编程软件,广泛应用于数学建模、数据分析和科学计算。MATLAB拥有丰富的函数库,涵盖线性代数、统计分析、优化算法、信号处理等多种数学操作,方便参赛者构建模型和实现算法。 在提供的文件列表中,有几个关键文件: d题论文(1).docx:这可能是参赛队伍对D题的解答报告,详细记录了他们对问题的理解、建模过程、求解方法和结果分析。 D_1.m、ratio.m、importfile.m、Untitled.m、changf.m、pailiezuhe.m、huitu.m:这些是MATLAB源代码文件,每个文件可能对应一个特定的计算步骤或功能。例如: D_1.m 可能是主要的建模代码; ratio.m 可能用于计算某种比例或比率; importfile.m 可能用于导入数据; Untitled.m 可能是未命名的脚本,包含临时或测试代码; changf.m 可能涉及函数变换; pailiezuhe.m 可能矩阵的排列组合相关; huitu.m 可能用于绘制回路图或流程图。 matlab111.mat:这是一个MATLAB数据文件,存储了变量或矩阵等数据,可能用于后续计算或分析。 D-date.mat:这个文件可能包含D题相关的特定日期数据,或是模拟过程中用到的时间序列数据。 从这些文件可以推测,参赛队伍可能利用MATLAB完成了数据预处理、模型构建、数值模拟和结果可视化等一系列工作。然而,具体的建模细节和解决方案需要查看解压后的文件内容才能深入了解。 在数学建模过程中,团队需深入理解问题本质,选择合适的数学模
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值