JMM模型与并发三大特性

news2025/1/20 3:53:16

如何学: 分理解并发的三大特性,JMM工作内存和主内存关系,知道多线程之间如何通信的,掌握volatile能保证可见性和有序性,CAS就可以了

并发和并行

目标都是最大化CPU的使用率
并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是 从宏观来看,二者都是一起执行的。

并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执 行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间 分成若干段,使多个进程快速交替的执行。

并发三大特性

并发编程Bug的源头:可见性、原子性和有序性问题

  1. 可见性

当一个线程修改了共享变量的值,其他线程能够看到修改的值。Java 内存模型是通过在变量 修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介 的方法来实现可见性的。
如何保证可见性

  • 通过 volatile 关键字保证可见性。
  • 通过 内存屏障保证可见性。
  • 通过 synchronized 关键字保证可见性。
  • 通过 Lock保证可见性。
  • 通过 final 关键字保证可见性
  1. 有序性

即程序执行的顺序按照代码的先后顺序执行。JVM 存在指令重排,所以存在有序性问题。
如何保证有序性

  • 通过 volatile 关键字保证可见性。
  • 通过 内存屏障保证可见性。
  • 通过 synchronized关键字保证有序性。
  • 通过 Lock保证有序性。
  1. 原子性

一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。在 Java 中,对基本数据类型的变量的读取和赋值操作是原子性操作(64位处理器)。**不采取任 何的原子性保障措施的自增操作并不是原子性的。 **
如何保证原子性

  • 通过 synchronized 关键字保证原子性。
  • 通过 Lock保证原子性。
  • 通过 CAS保证原子性。

JMM :JAVA多线程通信模型——共享 内存模型

image.png

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

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

image.pngimage.png

volatile的内存语义

volatile的特性

  • 可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最 后的写入。
  • 有序性:对volatile修饰的变量的读写操作前后加上各种特定的内存屏障来禁止指 令重排序来保障有序性。

volatile写-读的内存语义

  • 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到 主内存。
  • 当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,线程接下来 将从主内存中读取共享变量

volatile可见性实现原理

JMM内存交互层面实现

volatile修饰的变量的read、load、use操作和assign、store、write必须是连续的,即修改后必须立即同步回主内存,使用时必须从主内存刷新,由此保证volatile变量操作对多线程 的可见性。

硬件层面实现

通过lock前缀指令,会锁定变量缓存行区域并写回主内存,这个操作称为“缓存锁定”, 缓存一致性机制会阻止同时修改被两个以上处理器缓存的内存区域数据。**一个处理器的缓存回写到内存会导致其他处理器的缓存无效。 **

总结: JAVA中可见性如何保证

  • storeLoad内存屏障 ==> (汇编层面指令)方面使用Lock指令“ lock; addl $0,0(%%rsp) ”

例如volatile,锁机制
当前线程对当前共享变量的操作会存在读不到,或者不能立刻感知另一个线程对共享变量的写操作

  • 通过上下文切换,例如Thread.yield();

image.png
image.png

volatile有序性实现原理

在JVM层面中,在volatile写和volatile读之间,会添加内存屏障storeLoad , 禁止指令重排,从而保证有序性

private volatile static int i;
private static a;


new Thread(() -> {
    // volatile 写
	i = 2;

    // 会添加内存屏障storeLoad , 禁止指令重排,从而保证有序性

    // volatile 读
    a = i;

},"thread1")

指令重排序

即只要程序的最终结果与它顺序化情况的结果相等,那么指令的执行顺序可以与代码顺序不一致,此过程叫指令的重排序

as-if-serial

as-if-serial语义的意思是:不管怎么重排序(编译器和处理器为了提高并行度),(单线
程)程序的执行结果不能被改变。

volatile重排序规则

1.  第二个操作是volatile写,不管第一个操作是什么都不会重排序
2.  第一个操作是volatile读,不管第二个操作是什么都不会重排序
3.  第一个操作是volatile写,第二个操作是volatile读,也不会发生重排序

JMM内存屏障插入策略

image.png

JVM层面的内存屏障

在JSR规范中定义了4种内存屏障:

  • LoadLoad屏障:(指令Load1; LoadLoad; Load2),在Load2及后续读取操作要读取的数 据被访问前,保证Load1要读取的数据被读取完毕。
  • LoadStore屏障:(指令Load1; LoadStore; Store2),在Store2及后续写入操作被刷出前, 保证Load1要读取的数据被读取完毕。
  • StoreStore屏障:(指令Store1; StoreStore; Store2),在Store2及后续写入操作执行前, 保证Store1的写入操作对其它处理器可见。
  • StoreLoad屏障:(指令Store1; StoreLoad; Load2),在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。在大多数处理器的 实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能

由于x86只有store load可能会重排序,所以只有JSR的StoreLoad屏障对应它的mfence或 lock前缀指令,其他屏障对应空操作

CPU高速缓存架构

CPU缓存即高速缓冲存储器,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直接调用,减少CPU的等待时间,提高了系统的效率。

image.png

缓存一致性(Cache coherence)

计算机体系结构中,缓存一致性是共享资源数据的一致性,这些数据最终存储在多个本地缓 存中。当系统中的客户机维护公共内存资源的缓存时,可能会出现数据不一致的问题,这在多处 理系统中的cpu中尤其如此。

总线窥探(Bus Snooping)

总线窥探(Bus snooping)是缓存中的一致性控制器(snoopy cache)监视或窥探总线事务的一种方案,其目标是在分布式共享内存系统中维护缓存一致性

工作原理

当特定数据被多个缓存共享时,处理器修改了共享数据的值,更改必须传播到所有其他具有 该数据副本的缓存中。这种更改传播可以防止系统违反缓存一致性。

窥探协议类型

根据管理写操作的本地副本的方式,有两种窥探协议:
Write-invalidate
当处理器写入一个共享缓存块时,其他缓存中的所有共享副本都会通过总线窥探失效。这种 方法确保处理器只能读写一个数据的一个副本。其他缓存中的所有其他副本都无效。这是最常用 的窥探协议。MSI、MESI、MOSI、MOESI和MESIF协议属于该类型。
Write-update
当处理器写入一个共享缓存块时,其他缓存的所有共享副本都会通过总线窥探更新。这个方
法将写数据广播到总线上的所有缓存中。它比write-invalidate协议引起更大的总线流量。这就 是为什么这种方法不常见。Dragon和firefly协议属于此类别。

MESI协议

MESI协议是一个基于写失效的缓存一致性协议,是支持回写(write-back)缓存的最常用
协议。
状态缓存行有4种不同的状态:

  • 已修改Modified (M)

缓存行是脏的(dirty),与主存的值不同。如果别的CPU内核要读主存这块数据,该缓存行必 须回写到主存,状态变为共享(S).

  • 独占Exclusive (E)

缓存行只在当前缓存中,但是干净的–缓存数据同于主存数据。当别的缓存读取它时,状态变为 共享;当前写数据时,变为已修改状态。

  • 共享Shared (S)

缓存行也存在于其它缓存中且是未修改的。缓存行可以在任意时刻抛弃。

  • 无效Invalid (I)

缓存行是无效的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1095557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Arcgis对图像重采样、打开查看运行结果的窗口、逐像元提取数值

1、Arcgis对图像重采样 然后打开数据管理工具-栅格-栅格处理-重采样 打开后,此处我们输入数据用导入的影像,X和Y代表重采样的大小为8*8 注意:输出文件需要有文件后缀,否则报错。 采样后,像元就变成了8*8一个像元。 2…

安装gymnasium[box2d]的问题

安装时总会报错 Building wheels for collected packages: box2d-pyBuilding wheel for box2d-py (setup.py) ... errorerror: subprocess-exited-with-error python setup.py bdist_wheel did not run successfully.│ exit code: 1╰─> [16 lines of output]Using setup…

gitlab自编译 源码下载

网上都是怎么用 gitlab,但是实际开发中有需要针对 gitlab 进行二次编译自定义实现功能的想法。 搜索了网上的资料以及在官网的查找,查到了如下 gitlab 使用 ruby 开发。 gitlab 下载包 gitlab/gitlab-ce - Packages packages.gitlab.com gitlab/gitl…

leetcode做题笔记174. 地下城游戏

恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0…

21GA-ELM,遗传算法优化ELM预测,并和优化前后以及真实数值进行对比,确定结果,基于MATLAB平台,程序已经调通,可以直接运行,需要直接拍下。

GA-ELM,遗传算法优化ELM预测,并和优化前后以及真实数值进行对比,确定结果,基于MATLAB平台,程序已经调通,可以直接运行,需要直接拍下。 21matlab时间序列预测极限学习遗传优化算 (xiaohongshu.co…

2023年(2024届)双非保研历程(中南、东南、浙大、信工所、国防科大、北邮)

个人情况 学校层次:双非 专业:信息安全(投的基本都是网安) 排名:2/66 英语:六级565,四级560 竞赛:大英赛国三、美赛H、蓝桥杯省一、数竞省一、词达人省一、数模国赛省三。 论文&…

【LeetCode刷题(数据结构与算法)】:二叉树之左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 示例 2: 输入: root [1] 输出: 0 这都题目用递归的方法就可以解决…

牛客周赛 Round 15

A、 题目描述 游游拿到了一个正整数,她希望将它切割成两部分,使得它们的和为偶数。游游想知道有多少种合法的切割方案? 注:切割后的正整数允许出现前导零。 输入描述: 一个正整数,大小不超过10^100000 输出描述: 一个整…

参数解析(牛客)

目录 一、题目 二、代码 一、题目 二、代码 #include <iostream> #include <vector> using namespace std;int main() {string s;getline(cin, s);int i 0;vector<string>ret;while (i < s.size()){if (s[i] )//遇到空格直接跳过{i;}else if (s[i] …

[部署网站]01安装宝塔面板搭建WordPress

宝塔面板安装WordPress&#xff08;超详细&#xff09;_Wordpress主题网 参考教程 宝塔面板 - 简单好用的Linux/Windows服务器运维管理面板 官网 1.首先你需要一个服务器或者主机 &#xff08;Windows系统或者Linux系统都可以&#xff09; 推荐Linux系统更稳定&#xff0c;…

基于Java的个人健康管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

LeetCode 1095. 山脉数组中查找目标值【数组,二分】1827

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

CEC2013(MATLAB):霸王龙优化算法(Tyrannosaurus optimization)求解CEC2013

一、霸王龙优化算法TROA 霸王龙优化算法&#xff08;Tyrannosaurus optimization&#xff0c;TROA&#xff09;由Venkata Satya Durga Manohar Sahu等人于2023年提出&#xff0c;该算法模拟霸王龙的狩猎行为&#xff0c;具有搜索速度快等优势。 参考文献&#xff1a;Venkata S…

CEC2013(MATLAB):螳螂搜索算法(Mantis Search Algorithm,MSA)求解CEC2013

一、螳螂搜索算法 螳螂搜索算法&#xff08;Mantis Search Algorithm&#xff0c;MSA&#xff09;由Mohamed Abdel-Basset等人于2023年提出&#xff0c;该算法模拟螳螂独特的狩猎和性同类相食行为。MSA由三个优化阶段组成&#xff0c;包括寻找猎物&#xff08;探索&#xff09…

The normalized eigenfunction may not be uniformly bounded

See Article The Uniform Lipschitz Continuity of Eigenvalues of Sturm–Liouville Problems with Respect to the Weighted Function Jing Xu , Zhiwen Liu and Jiangang Qi https://doi.org/10.3390/sym15040911

Android Framework通信:Binder

文章目录 前言一、Linux传统跨进程通信原理二、Android Binder跨进程通信原理1、动态内核可加载模块2、内存映射3、Binder IPC 实现原理 三、Android Binder IPC 通信模型1、Client/Server/ServiceManager/驱动Binder与路由器之间的角色关系 2、Binder通信过程3、Binder通信中的…

Kibana安装、配置

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

如何利用 instructor 提高 RAG 的准确性和召回率

本文首发于博客 LLM 应用开发实践 RAG&#xff08;Retrieval Augmented Generation&#xff09;是一种检索增强生成技术&#xff0c;它利用大型语言模型来处理用户查询&#xff0c;RAG 技术的主要组成包括数据提取—embedding—创建索引—检索—排序&#xff08;Rerank&#xf…

智慧公厕:提升城市形象,为市民带来极致体验

智慧公厕是现代城市建设中不可或缺的一环&#xff0c;它不仅可以提升城市形象&#xff0c;还为市民提供更好的公厕体验。在这个快节奏的时代&#xff0c;人们对公共设施的要求也越来越高&#xff0c;智慧公厕的出现正好满足了市民们的需求。本文以智慧公厕源头厂家广州中期科技…

ThreadLocal全面解析

目录 一、ThreadLocal的介绍1、简介2、基本使用3、ThreadLocal与synchronized的区别 二、ThreadLocal的内部结构1、jdk早期设计2、JDK8设计3、内存泄露 三、ThreadLocal的核心方法源码1、set方法2、get方法3、initialValue方法4、withInitial方法5、remove方法6、子类Inheritab…