JVM原理(二十):JVM的原子性、可进行与有序性详解

【数电课程设计】---出租车计价器 文章目录1、任务要求2、方案3、收获 1、任务要求 2、方案 3、收获 阅读详情

1. 原子性、可进行与有序性

1.1. 原子性

Java内存模型围绕着在并发过程中如何处理原子性、可见性和有序性这三个特征来建立的。


Java内存模型来直接保证的原子性变量操作包括read、load、assign、use、store和write这六个。我们大致可以认为,基本数据类型的访问、读写都是具备原子性的。

synchronized关键字与虚拟机的关系

如果应用场景需要一个更大范围的原子性保证(经常会遇到),Java内存模型还提供了lock和unlock操作来满足这种需求,尽管虛拟机未把lock和unlock操作直接开放给用户使用,但是却提供了更高层次的字节码指令monitorenter和monitorexit来隐式地使用这两个操作。这两个字节码指令反映到Java代码中就是同步块一synchronized关键字,因此在synchronized块之间的操作也具备原子性。

1.2. 可见性

可见性就是指当前一个线程修改了共享变量的值时,其他线程能够立即得知这个修改。


实现:Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方式来实现可见性。

区别:普通变量与volatile(哇了特)变量的区别是:volatile的特殊规则保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。因此我们可以说volatile保证了多线程操作时变量的可见性,而普通变量则不能保证这一点。

除了volatile之外,Java还有两个关键字能实现可见性,它们是synchronized和final。同步块的可见性:是由“对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行store、write操作)”这条规则获得的。而final关键字的可见性是指:被final修饰的字段在构造器中---旦被初始化完成,并且构造器没有把“this"的引用传递出去(this引用逃逸是一件很危险的事情,其他线程有可能通过这个引用访问到“初始化了一半”的对象),那么在其他线程中就能看见final字段的值。

1.3. 有序性

如果在本线程内观察,所有的操作都是有序的;如果在一个线程中观察另一个线程,所有的操作都是无序的。

所有的操作都是无序的。前半句是指“线程内似表现为串行的语义”(Within-Thread As-If-Serial Semantics),后半句是指“指令重排序”现象和“工作内存与主内存同步延迟”现象。


Java语言提供了volatile和synchronized两个关键字保证线程之间操作的有序性。

volatile关键字本身就包含了禁止指令重排序的语义。

synchronized则是由“一个变量在同一时刻只允许一条线程对其进行lock操作”这条规则获得的,这个规则决定了持有同一个锁的两个同步块只能串行地进入。

2. 先行发生原则

概念:现在就来看看“先行发生”原则指的是什么。先行发生是Java内存模型中定义的两项操作之间的偏序关系,比如说操作A先行发生于操作B,其实就是说在发生操作B之前,操作A产生的影响能被操作B观察到,“影响”包括修改了内存中共享变量的值、发送了消息、调用了方法等。

作用:它是判断数据是否存在竞争,线程是否安全地非常有用地手段。


如果两个操作之间的关系不在此列,并且无法从下列规则推导出来,则它们就没有顺序性保障,虚拟机可以对它们随意地进行重排序。

  • 程序次序规则( Program Order Rule) :在一个线程内,按照控制流顺序,书写在前面的操作先行发生于书写在后面的操作。注意,这里说的是控制流顺序而不是程序代码顺序,因为要考虑分支、循环等结构。

  • 管程锁定规则(Monitor Lock Rule) :一个unlock操作先行发生于后面对同一个锁的lock操作。这里必须强调的是“同一个锁”,而“后面”是指时间上的先后。

  • volatile变量规则( Volatile Variable Rule) :对一个volatile变量的写操作先行发生于后面对这个变量的读操作,这里的“后面”同样是指时间上的先后。

  • 线程启动规则(Thread Start Rule):Thread对象的start()方法先行发生于此线程的每一个动作。

  • 线程终止规则(Thread Termination Rule) :线程中的所有操作都先行发生于对此线程的终止检测,我们可以通过Thread:join()方法是否结束、Thread:isAlive()的返 回值等手段检测线程是否已经终止执行。

  • 线程中断规则(Thread Interruption Rule) :对线程interrupt(方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Threa:interrupted0方法检测到是否有中断发生。

  • 对象终结规则(Finalizer Rule) : 一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize(方法的开始。

  • 传递性 (Transitivity) :如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。

windows 配置 libxml2 路径:\libiconv-1.9.2-1-src.zip\src\libiconv\1.9.2\libiconv-1.9.2\include\。执行完后,在当前win32目录中会生成了一个bin.msvc目录,其中就有开发需要的libxml2.lib和libxml2.dll文件。将 libiconv.la 复制到 新建的 lib 目录,并将其改名为 iconv.lib。路径:libiconv-1.9.2-1-bin.zip\lib\。将如下的 iconv.h 复制到新建的 include 目录。 阅读详情

相关推荐

EPLAN电气设计精华 -模拟量传感器画法全解

本文介绍了EPLAN中模拟量压力传感器的标准画法要点,重点解析了电流型(4-20mA)、电压型(0-10V/0-5V)和特定应用型三种传感器的核心特点、典型符号、接线方式及应用场景。文章提供了EPLAN设备标识符示例,并分享了一个实际项目案例(XJC-Y01-20-4M传感器配合XJC-608T-F变送器和GSEE.GXLK-AI4S-I模块的应用),强调绘制前查阅技术资料的重要性。内容简明实用,有助于规范电气设计中的传感器绘制。

Qinmingyue13的博客 1181

JVM——JMM内存模型

java内存模型

测试 697

FIddler+Proxifer 实现PC客户端抓包详细教程

FIddler+Proxifer 实现PC客户端抓包详细教程

森明帮大于黑虎帮的博客 1万+

JVM原理(二十):JVM虚拟机内存的三特性详解

先行发生是Java内存模型中定义的两项操作之间的偏序关系,比如说操作A先行发生于操作B,其实就是说在发生操作B之前,操作A产生的影响能被操作B观察到,“影响”包括修改了内存中共享变量的值、发送了消息、调用了方法等。:被final修饰的字段在构造器中---旦被初始化完成,并且构造器没有把“this"的引用传递出去(this引用逃逸是一件很危险的事情,其他线程有可能通过这个引用访问到“初始化了一半”的对象),那么在其他线程中就能看见final字段的值。这里必须强调的是“同一个锁”,而“后面”是指时间上的先后。

zuodingquan666的博客 923

Linux内核同步原语之队列自旋锁(Queued Spin Lock)深度解析

本文深度解析了Linux内核中的队列自旋锁(Queued Spin Lock)机制。通过对比传统自旋锁的瓶颈,详细阐述了队列自旋锁如何利用紧凑的4字节结构、每CPU节点数组和pending位优化,有效解决多核(SMP)系统中的缓存行乒乓和惊群效应,实现公平、高效的锁等待队列,从而显著提升内核在高并发场景下的可扩展性与性能。

weixin_29205061的博客 303

Fiddler Everywhere保姆级教程:10分钟搞定手机HTTPS抓包(附证书配置避坑指南)

本文提供Fiddler Everywhere移动端HTTPS抓包的保姆级教程,涵盖环境配置、代理设置、证书安装及常见问题排查。重点解析如何正确安装并信任Fiddler根证书以解密HTTPS流量,帮助开发者快速搭建抓包环境,高效分析应用网络行为,提升调试效率。

git9versioner的博客 705

jvm内存模型与原子性,可见性,有序性

一.内存模型: 每一个线程有一个工作内存,和主存是独立的。 工作内存存放主存重变量的值得拷贝。 线程独享的工作内存和主存的关系,如下图: 当数据从主内存复制到工作存储时,必须出现两个动作:第一,由主内存执行的读(read)操作;第二,由工作内存执行的相应的load操作; 当数据从工作内存拷贝到主内存时,也出现两个操作:第一个,由工作内存执行的存储(store)操作;第...

莫等闲的博客 706

2025虚幻游戏逆向工程解包尝试

2025虚幻游戏逆向工程解包指南 本文详细介绍了虚幻引擎5游戏逆向解包的完整流程,主要包括获取AES密钥、生成映射文件和导出资源三个关键步骤。作者在实际操作中遇到诸多难题:AES密钥获取工具存在加壳保护问题,映射文件生成器依赖复杂的VS编译环境,DLL注入工具的使用也存在技术门槛。通过多次尝试,作者发现部分游戏可直接搜索现成的AES密钥,而映射文件生成需要额外下载Memcury依赖库才能正常编译。文章提供了相关工具的下载链接和具体操作说明,但同时也指出每个环节都可能出现意外状况,逆向工程实际执行过程远比理论

wsdchong的博客 6150

Java内存模型(JMM)详解-原子性

1.什么是原子性 2.举例说明原子操作——深入探讨 i++ 操作 3.i++操作的具体内存实现过程分析 4.原子操作 5.如何解决原子性问题 6.CAS (Compare and swap) 7.如何使用CAS——手写原子实现 8.J.U.C包内的原子操作封装类(简单介绍不做详解) 9.CAS的三个问题

xiaoxiya55的博客 1779

JPA - @MappedSuperclass - 基类注解

目录前言代码示例 前言 @MappedSuperclass注解一般作为基类的注解,表眀该类是映射的超类,继承于它的子类实体在映射时会自动添加到子类实体的对应数据库表中,用于共同的属性代码复用和模型分离。 代码示例 BaseEntity.java import lombok.Getter; import lombok.Setter; import javax.persistence.MappedSuperclass; import java.util.Date; @Getter @Setter @Ma

Maggieq8324的博客 2065

Ubuntu 20.04下Cube-Studio云原生平台单机部署全攻略(附避坑指南)

本文详细介绍了在Ubuntu 20.04系统上单机部署Cube-Studio云原生平台的完整流程,包括环境准备、Docker配置、Rancher与Kubernetes集群部署以及Cube-Studio核心组件安装。特别提供了官方文档未涵盖的实战技巧和常见问题解决方案,帮助开发者高效完成部署并避免常见陷阱。

weixin_29313423的博客 464

Java内存模型(JMM-原子性、可见性、有序性)、volatile原理、

Java内存模型(JMM-原子性、可见性、有序性)、volatile原理、 共享模型之内存 多线程的三大特性(原子性、可见性、有序性) 之前将的synchronize底层Monitor主要关注的是访问共享变量时,保证临界区代码的原子性。下面进一步深入学习共享变量在多线程间的可见性问题与多条指令执行时的有序性问题 Java内存模型(重点) JMM 即Java Memory Model,它从Java层面定义了主存、工作内存抽象概念,底层对应着 CPU寄存器、缓存、硬件内存、CPU指令优化等。JMM体

Hill__Cheung的博客 514

利用requests库下载bilibili字幕文件

文章目录1. 前言2. 程序下载大法好2.1 挖掘思路2.2 核心知识点2.3 汇总代码 1. 前言   之前的博客介绍了使用工具下载B站视频,但美中不足的是无法下载字幕。为了提高效率,将下载字幕的工作用程序自动化处理。 2. 程序下载大法好 2.1 挖掘思路   在谷歌浏览器中按下F12,打开谷歌开发者工具。搜索subtitle,则会得到一个json文件,如下图所示:   在网页中空白位置点击查看网页源代码,然后通过搜索(Ctrl+f)查找subtitle,则会发现在subtitle_url中包含了对应

herosunly的博客 4万+

13.synchronized总结:怎么保证可见性、有序性、原子性?

synchronized是怎么保证原子性、可见性、有序性的?

chenzengnian123的博客 1万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

什么是 Java 中的原子性、可见性和有序性?

什么是 Java 中的原子性、可见性和有序性?原子性、可见性、有序性是 Java 并发编程的三大核心特性,任何并发 bug 基本都能归到这三类里面。

我哎GIS博客 3493

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

深入解析synchronized实现原理,如何保证原子性、有序性和可见性?

我觉得,关于synchronized你想要知道的,这里都有。

Steven Jon 9276

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

JUC多线程:从并发原理到实战,掌握原子性、可见性与有序性、MM与JVM内存模型的关系

在当今多核处理器时代,并发编程能力已成为开发者必备技能。但很多新手在面对"原子性"、"可见性"这些概念时总是一头雾水。本文将从最底层的CPU工作原理出发,通过生动比喻和代码案例,带你真正理解并发编程的底层逻辑。

2201_75525624的博客 1212

JVM 内存模型深度解析:原子性、可见性与有序性的实现

本文深入解析了JVM内存模型(JMM)在多线程环境下的核心机制。JMM通过主内存和工作内存的抽象划分,解决原子性、可见性和有序性三大并发问题。原子性通过synchronized锁和原子类实现;volatile关键字保障可见性;happens-before原则和内存屏障禁止指令重排序确保有序性。文章结合实际案例,分析了双重检查锁单例中volatile的必要性,以及i++等复合操作的原子性陷阱。最后指出这些机制是理解多线程安全的基础,也是面试高频考点。

dom_jun的博客 1502

【JVM原理详解】42-原子性与可见性与有序性

上一篇我们建立了JMM的基础抽象:主内存、工作内存、8种原子操作、内存屏障。这套抽象的存在,本质上是为了回答并发编程的三个根本问题——。这就是著名的"并发三要素"。几乎所有并发bug都能归结到这三者之一的被破坏。本篇逐一拆解三大特性的含义、JMM如何保证它们、以及指令重排序与数据竞争这些容易踩坑的概念。我们会用经典的i++问题和双重检查锁定(DCL)作为贯穿示例,把抽象规则落到代码层面。

gaochufukanyongren的博客 223

java并发(1)——JVM原子性、可见性、有序性

JVM原子性、可见性、有序性 Java内存模型是围绕着并发过程中如何处理原子性、可见性、有序性这三个特征来建立的,下面是这三个特性的实现原理: 原子性(Atomicity) 原子性是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始就不会被其他线程干扰。 由Java内存模型来直接保证的原子性变量操作包括read、load、use、assign、store和writ...

sicofield的专栏 1513

JVM内存模型详解(volatile原理、happen-before规则、内存屏障、可见性与有序性)

JVM内存模型是并发编程的理论基础。为什么多线程下变量修改对其他线程不可见?为什么指令会重排序?volatile如何保证可见性?happen-before原则是什么?理解主内存与工作内存的交互、指令重排序的本质、volatile的内存屏障、happen-before的传递性,才能掌握Java并发的本质。从"多线程下变量修改不可见"的经典bug出发,剖析JVM内存模型的核心原理。

比较是偷走幸福的小偷 1435

从对象头到内存屏障:synchronized 如何实现原子性、可见性与有序性

而且,可见性靠的不是你开的锁,而是加解锁那一瞬间的【内存屏障】。其实是我误会了锁的作用域——要命的时候发现,锁的是堆上的对象,对象头一切OK,但如果你给别的对象加锁,只保证持有锁的那段代码安全,可视野之外满是危险。有时候你写 Java,总觉得自己像个江湖上的镖师,左挡右护,不就想保证点安全么?最后,面试遇到“三大特性”,别只会嘴巴说“原子性、可见性、有序性好呀”——背后原理、对象头里藏的秘密,你得有点小故事,才敢拍胸脯说“我懂点门道”!谁说锁一定烂,关键看你会不会用,用得巧,JVM也会帮你省事。

2501_92441786的博客 939

原子性、可见性、有序性解决方案

原子性、可见性、有序性解决方案 (一)原子性 原子性是指:一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。在Java中当我们讨论一个操作具有原子性问题是一般就是指这个操作会被线程的随机调度打断。 JMM对原子性的保证大概分以下几种类型:java自带原子性、synchronized、Lock锁、原子操作类(CAS)。下面我们来一个一个细说。 1. java自带原子性 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,但是long和double类型是64位,在32位JV

物是人非,结局始终不美 9475

Java 多线程三大特性详解:原子性、可见性、有序性

本文系统讲解了Java并发编程的三大核心特性:原子性、可见性和有序性。针对原子性,详细介绍了四种实现方式:1) synchronized关键字通过Monitor机制和对象头Mark Word实现线程同步;2) ReentrantLock基于AQS框架提供更灵活的锁控制;3) 原子类利用CAS无锁机制实现高效并发;4) StampedLock采用乐观读策略优化读多写少场景。每种方案均配有完整代码示例和底层原理剖析,包括内存语义、锁升级路径、CAS操作等关键技术细节,帮助开发者深入理解并发控制机制。文章特别强调

qq_51972040的博客 995

为什么volatile能保证有序性不能保证原子性

对于内存模型的三大特性:有序性、原子性、可见性。 大家都知道 volatile 能保证可见性和有序性但是不能保证原子性,但是为什么呢? 一、原子性、有序性、可见性 1、原子性: (1)原子的意思代表着 ——“不可分”; (2)在整个操作过程中不会被线程调度器中断的操作,都可认为是原子性。原子性是拒绝多线程交叉操作的,不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作。例如 a...

王坦的博客 1172

JAVA—JVM详解

JAVA—JVM详解 一、JVM 1、什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。 通过JVM,Java实现了平

weixin_51356824的博客 2万+
上一篇: Hexo框架学习——从安装到配置
下一篇: 解决方案(一):虚拟机报错VMware Workstation 不可恢复错误: (vcpu-1)Exception 0xc0000005 (access violation) has occurr
依晴无旧
博客等级 码龄7年 1683粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值