【并发编程】Java内存模型

news2024/11/16 13:36:37

  

       📝个人主页:五敷有你      
 🔥系列专栏:并发编程
⛺️稳重求进,晒太阳

      这一章进一步深入学习共享变量在多线程间的【可见性】问题,与多条指令执行时的【有序性】问题

Java内存模型

JMM即Java Memory Model ,它定义了内存,工作内存的抽象概念,底层对应着CPU寄存器,缓存,硬件内存,CPU指令优化等。

JMM体现在如下几个方面

  • 原子性:保证指令不会受到线程上下文切换的影响
  • 可见性:保证指令不会收到CPU缓存的影响
  • 有序性:保证指令不会受CPU指令并行优化的影响

可见性

退不出的循环

先来看一个现象,main线程对run变量的修改对于t线程不可见,导致t线程无法停止

stat
static boolean run=true;
public static void main(String[] args) throws InterruptedException {
    Thread t1=new Thread(()->{
       while (run){
           //...一直运行
       }
    });
    t1.start();
    Thread.sleep(2000);
    run=false;
    log.debug("停止{}",run);



}

为什么呢?分析一下

初始状态,t线程刚开始从主存读取到run的值到工作内存

2 因为t线程要频繁主存中读取run的值,JIT编译器会将run的值缓存至自己的工作内存中的高速缓存中,。减少对主存中run的访问。提高效率

3、 1s后,mian线程修改了run的值,并同步至主存,而t是从自己工作内存中的高速缓存中读取这个变量的值,结果永远是旧的值

可见性解决方法

  1. volatile(易变关键字)

它可以用来修饰成员变量和静态成员变量,不能修饰局部变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作 volatile 变量都是直接操作主存

  1. synchorinzed

        某一个线程进入synchronized代码块前后,线程会加锁,清空工作内存,从主内存拷贝共享变量最新的值到工作区称为副本

        执行代码,将修改后的副本刷新回到主存中,线程释放锁

可见性VS原子性

        前面例子体现的是可见性,它保证的是在多个线程之间,一个线程对volatile变量的修改对另一个线程可见,不能保证原子性,仅用一个写线程,多个读线程的清空。

上例的字节码文件理解是这样的:

        比较一下,之前线程安全时举得例子:两个线程一个i++,一个i--,只能保证看到最新值,不能解决指令交错的问题。

        在下面,线程2读取值0 然后切换 线程1读取i的值, 之后准备常熟1 ,然后写回JMM,之后线程2 修改后写回JMM, 结果是-1,与期待不符,这是原子性问题,而volatile是解决的可见性的问题

        注意 synchronized 语句块既可以保证代码块的原子性,也同时保证代码块内变量的可见性。但缺点是synchronized 是属于重量级操作,性能相对更低

        如果在前面示例的死循环中加入 System.out.println() 会发现即使不加 volatile 修饰符,线程 t 也能正确看到对 run 变量的修改了,想一想为什么?

如下,在println中有synchronized

有序性

JVM会在不影响正确性的前提下,可以调整语句的执行顺序,思考下面的一段代码

static int i; static int j; //在某个线程内执行如下赋值操作 i=...; j=...;

可以看到,至于是先执行i,还是先执行j, 对最终结果不会产生影响,所以,上面的代码真正执行时,既可以是

i=...; j=...;

也可以是

i=...; j=...;

这种特性称之为指令重排序,在多线程下,【指令重排序】会影响正确性,为什么要有指令重排序这项优化呢?从CPU执行指令的原理来理解

---------【并发编程】指令集并行原理-CSDN博客

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

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

相关文章

STM32实现软件IIC协议操作OLED显示屏(1)

时间记录:2024/1/25 一、IIC协议介绍 (1)协议介绍 IIC(又称I2C,Inter-Integrated Circuit),即集成电路总线,是一种两线式串行总线,由PHILIPS公司开发,用…

MSG3D论文解读

论文在stgcn与sta-lstm基础上做的。下面讲一下里面的方法: 1.准备工作 符号。这里是对符号进行解释。 一个人体骨骼图被记为G(v,E) 图卷积: 图卷积定义 考虑一种常用于处理图像的标准卷积神经网络 (CNN)。输入是像素网格。每个像素都有一个数据值向…

喜报|「云原生数据库PolarDB」、「阿里云瑶池一站式数据管理平台」揽获“2023技术卓越奖”

日前,国内知名IT垂直媒体&技术社区IT168公布2023年“技术卓越奖”评选结果,经由行业CIO/CTO大咖、技术专家及IT媒体三方的联合严格评审,阿里云瑶池数据库揽获两项大奖:云原生数据库PolarDB荣获“2023年度技术卓越奖”&#xf…

GraphQL的力量:简化复杂数据查询

1. GraphQL GraphQL 是一种由 Facebook 开发并于 2015 年公开发布的数据查询和操作语言,也是运行在服务端的运行时(runtime)用于处理 API 查询的一种规范。不同于传统的 REST API,GraphQL 允许客户端明确指定它们需要哪些数据&am…

.net访问oracle数据库性能问题

问题: 生产环境相同的inser语句在别的非.NET程序相应明显快于.NET程序,执行时间相差比较大,影响正常业务运行,测试环境反而正常。 问题详细诊断过程 问题初步判断诊断过程: 查询插入慢的sql_id 检查对应的执行计划…

Storm

1.1. 概念 Storm 是一个免费并开源的分布式实时计算系统。利用 Storm 可以很容易做到可靠地处理无限的 数据流,像 Hadoop 批量处理大数据一样,Storm 可以实时处理数据。 1.2. 集群架构 1.2.1 Nimbus(master-代码分发给 Supervisor&#xf…

VS Code使用Git管理开发项目流程

以VSCode远程连接虚拟机开发为例,已经配置好SSH 在Github上搜索心仪的项目,比如权限管理 点击fork到自己账户仓库 虚拟机下创建一个目录 1)mkdir java_test 2)切换到java_test 初始化并克隆项目 1) git init:初始化仓库 2) g…

数字孪生系统的难点

数字孪生系统的开发和实施涉及一些技术难点,这些难点需要综合应用多个领域的知识和技术来克服。以下是一些数字孪生系统开发中的技术难点,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1…

Conda 使用environment.yml创建一个新的Python项目

Conda系列: 翻译: Anaconda 与 miniconda的区别Miniconda介绍以及安装Conda python运行的包和环境管理 入门Conda python管理环境environments 一 从入门到精通Conda python管理环境environments 二 从入门到精通Conda python管理环境environments 三 从入门到精通…

电子行业含砷废水,深度除砷技术

砷是一种类金属元素,砷化物生物毒性极强,是国际公认的第一类致癌物。因此,这些含砷废水必须经过一定的处理才能排放到环境中。那么,哪些行业会产生含砷废水呢?在地球上,砷是一种常见的元素。在自然界中,砷…

程序执行原理揭秘:你的代码是如何“跑”起来的?

程序执行原理揭秘:你的代码是如何“跑”起来的? 一、执行前的准备工作 我们先来看一下程序执行前需要做哪些准备工作。 我们首先需要了解程序的格式。你可以把程序比作一本书,而程序的格式就是这本书的版式,它决定了书的结构和…

【Python-PyCharm】PyCharm 安装并创建项目(保姆级教程)

【Python-PyCharm】PyCharm 安装并创建项目(保姆级教程) 1)PyCharm 下载2)PyCharm 安装3)创建项目(使用PyCharm编写程序) 使用 PyCharm 需要配置 Python 环境变量,详情如下&#xff…

使用DBSyncer同步Oracle11g数据到Mysql5.7中_实现全量数据同步和增量数据实时同步_操作过程---数据同步之DBSyncer工作笔记007

之前都是用mysql和Postgresql之间进行同步的,已经实现了数据的实时同步,现在要实现Oracle数据库到Mysql数据库的全量,以及增量同步. 因为之前配置的不对,这里架构名写成了orcl,所以导致,虽然能连接上,但是,在进行数据同步的时候,看不到表,所以这里说一下如何进行连接 这里,首先…

力扣80、删除有序数组中的重复项Ⅱ(中等)

1 题目描述 图1 题目描述 2 题目解读 对于有序数组nums,要求在不使用额外数组空间的条件下,删除数组nums中重复出现的元素,使得nums中出现次数超过两次的元素只出现两次。返回删除后数组的新长度。 3 解法一:双指针 双指针法可以…

分享7种SQL的进阶用法

分享7种SQL的进阶用法 前言 还只会使用SQL进行简单的insert、update、detele吗?本文给大家带来7种SQL的进阶用法,让大家在平常工作中使用SQL简化复杂的代码逻辑。 1.自定义排序(ORDER BY FIELD) 在MySQL中ORDER BY排序除了可以…

HNSW算法

From: HNSW算法(nsmlib/hnswlib)-CSDN博客HNSW算法的基本原理及使用 - 知乎 HNSW是一种广泛使用的ANN图索引结构,包括DiskANN、DF-GAS、SmartSSD等。本文档主要总结HNSW的结构与工作流程,便于后期研究其工作流程在迁移到CSD中存在的I/O问题…

【LeetCode: 148. 排序链表 + 链表 + 归并排序】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

防火墙源NAT配置

拓扑 需求 生产区在工作时间内可以访问服务器区,仅可以访问HTTP服务器。办公区全天可以访问服务区,其中,10.0.2.20可以访问FTP服务器和HTTP服务器 10.0.2.10仅可以ping通10.0.3.10办公区在访问服务区时采用匿名认证方式进行上网行为管理。办…

SAP创建资产号码和分配资产价值

文章目录 1 Creat new asset2 View asset3 Create old asset4 Transfer value5 Summary 1 Creat new asset T-code(AS01) 2 View asset T-CODE : AS03 3 Create old asset T-code(as91) 4 Transfer value T-code(ABLDT) If there is following information a…

双向队列的创建队首与队尾的操作deque()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 双向队列的创建 队首与队尾的操作 deque() [太阳]选择题 请问以下代码输出的结果是? from collections import deque print("【创建双向队列】d deque()") d deque(…