Java基础之并发理论基础

news2024/11/24 18:40:11

Java基础之并发理论基础

  • 一、为什么需要多线程
  • 二、线程不安全
    • 1、三要素之一可见性(CPU缓存引起)
    • 2、三要素之一原子性(分时复用引起)
    • 3、三要素之一有序性(重排序引起)


一、为什么需要多线程

  • CPU 增加了缓存,以均衡与内存的速度差异;// 导致 可见性问题
  • 操作系统增加了进程、线程,以分时复用 CPU,进而均衡 CPU 与 I/O 设备的速度差异;// 导致 原子性问题
  • 编译程序优化指令执行次序,使得缓存能够得到更加合理地利用。// 导致 有序性问题

二、线程不安全

如果多个线程对同一个共享数据进行访问而不采取同步操作的话,那么操作的结果是不一致的。
例如1000 个线程同时对 cnt 执行自增操作,操作结束之后它的值有可能小于 1000。

1、三要素之一可见性(CPU缓存引起)

可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到。

//线程1执行的代码
int i = 0;
i = 10;
 
//线程2执行的代码
j = i;

假若执行线程1的是CPU1,执行线程2的是CPU2。由上面的分析可知,当线程1执行 i =10这句时,会先把i的初始值加载到CPU1的高速缓存中,然后赋值为10,那么在CPU1的高速缓存当中i的值变为10了,却没有立即写入到主存当中。

此时线程2执行 j = i,它会先去主存读取i的值并加载到CPU2的缓存当中,注意此时内存当中i的值还是0,那么就会使得j的值为0,而不是10.

这就是可见性问题,线程1对变量i修改了之后,线程2没有立即看到线程1修改的值。

2、三要素之一原子性(分时复用引起)

原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

举个简单的例子,看下面这段代码:

int i = 1;

// 线程1执行
i += 1;

// 线程2执行
i += 1;

这里需要注意的是:i += 1需要三条 CPU 指令

  1. 将变量 i 从内存读取到 CPU寄存器;
  2. 在CPU寄存器中执行 i + 1 操作;
  3. 将最后的结果i写入内存(缓存机制导致可能写入的是 CPU 缓存而不是内存)。

由于CPU分时复用(线程切换)的存在,线程1执行了第一条指令后,就切换到线程2执行,假如线程2执行了这三条指令后,再切换会线程1执行后续两条指令,将造成最后写到内存中的i值是2而不是3。

3、三要素之一有序性(重排序引起)

有序性:即程序执行的顺序按照代码的先后顺序执行。
但在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序。重排序分三种类型:

  • 编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
  • 指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-Level Parallelism, ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
  • 内存系统的重排序。由于处理器使用缓存和读 / 写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。

从 java 源代码到最终实际执行的指令序列,会分别经历下面三种重排序:
在这里插入图片描述
上述的 1 属于编译器重排序,2 和 3 属于处理器重排序。这些重排序都可能会导致多线程程序出现内存可见性问题。对于编译器,JMM 的编译器重排序规则会禁止特定类型的编译器重排序(不是所有的编译器重排序都要禁止)。对于处理器重排序,JMM 的处理器重排序规则会要求 java 编译器在生成指令序列时,插入特定类型的内存屏障(memory barriers,intel 称之为 memory fence)指令,通过内存屏障指令来禁止特定类型的处理器重排序(不是所有的处理器重排序都要禁止)。


  • 平安夜到了,向唯美的星空许个愿,愿你生活甜蜜平静;向悠扬的钟声祈个祷,愿你事业路上顺利平坦;向亲爱的朋友问声好,愿你快乐无忧,幸福安康,一生平安。祝平安夜快乐!
  • 人格的完善是本,财富的确立是末。
  • 你的饭钱,你的零用钱,你所有所有未步入社会前的支出都是父母给你的,你有什么资格颓废?你还你爸妈养你的钱了吗?
  • 一直相信,会有一个高度,让我看到不一样的风景。
  • 祝你平安夜乐相伴,福相随。
  • 愿你幸福永健康,好运财运长伴你!
  • 如果你总是做自己擅长的事,那你将永远不会进步。
  • 祝你平安夜乐相伴,福相随。
  • 然万物好像逝去了,但是,你瞧!那火红的枫叶在树枝上摇摆着,就像是一大群顽皮的孩子在手拉手一起跳着欢快的舞蹈呢。有些枫叶因跳舞不慎,从树枝上跌了下来,瞬间化作了一只只飞舞的蝴蝶,在空中飞来飞去。
  • 平安夜我一个人过,圣诞节我一个人过,跨年夜我一个人过,元旦我还是一个人,快到的生日是不是也要一个人过。

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

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

相关文章

springcloud3 EurekaServer集群的搭建1

一 EurekaServer集群搭建 1.1 逻辑流程 服务的注册与发现 服务注册:向注册中心进行注册登记。 服务发现:从注册中心中获取服务器信息。 整个流程 1.首先eurekaServer先进行启动, 2.服务提供者开始启动并将自己的信息注册到EurekaServer上(前…

如何获取java加载器和类完整结构的方法?

类加载器的作用与类缓存: 类加载器的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口。 …

红绿灯(交通信号灯)检测数据集

深度学习目标检测:红绿灯(交通信号灯)检测数据集 目录 深度学习目标检测:红绿灯(交通信号灯)检测数据集 1.红绿灯数据集说明 (1)Traffic-Lights-Dataset-Domestic (2)Traffic-Lights-Dataset-Foreign …

第12部分 交换机基本配置

目录 12.1 交换机简介 12.2 实验1:交换机基本配置 1.实验目的 2.实验拓扑 3.实验步骤 12.3 实验2:交换机端口安全 1.实验目的 2.实验拓扑 3.实验步骤 4.实验调试 12.4 实验3:交换机的密码恢复 1.实验目的 2.实验拓扑 3.实验步骤…

React学习8(新旧生命周期)

组件的生命周期(旧) react生命周期(旧) 1.初始化阶段:由ReactDOM.render()触发---初次渲染 1.constructor(){} 2.componentWillMount() {} 3.render() {} 4.componentDidMount() {}----常用,一般在这个钩子…

ElasticSearch的数据存储及写入原理

数据存储 数据存储介绍 Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。 为了方便大家理解,我们将 Elasticsearch 里存储文档数据和关系型数据库 MySQL 存储数据的概念进行一个类比。 注意:Types 的概念已经被逐渐弱化&…

上海亚商投顾:沪指全天窄幅震荡 大消费板块再掀涨停潮

上海亚商投顾前言:无惧大盘大跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪沪指全天窄幅震荡,创业板指高开低走。医药股大幅分化,新华制药6连板,股价创出历…

软件测试丨单元测试框架怎么搭?新版的Junit5有哪些神奇之处?

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。 总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部…

12306接口采集

铁路客户服务中心https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date2022-12-22&leftTicketDTO.from_stationCQW&leftTicketDTO.to_stationETW&purpose_codesADULT请求头 Accept: */* Accept-Language: zh-CN,zh;q0.9 Cache-Control: no-cach…

高并发编程之JUC 三大辅助类和读写锁

7 JUC 三大辅助类 JUC 中提供了三种常用的辅助类,通过这些辅助类可以很好的解决线程数量过 多时 Lock 锁的频繁操作。这三种辅助类为: • CountDownLatch: 减少计数• CyclicBarrier: 循环栅栏• Semaphore: 信号灯 下面我们分别进行详细的介绍和学习…

JavaScript基础之循环

1、循环 1.1、for循环 语法结构: for(初始化变量; 条件表达式; 操作表达式 ){//循环体 } 名称作用初始化变量通常被用于初始化一个计数器,该表达式可以使用 var 关键字声明新的变量,这个变量帮我们来记录次数。条件表达式用于确定每一次循…

Java on Azure Tooling 11月更新|远程调试支持与 App Settings 增强

作者:Jialuo Gan Program Manager, Developer Division at Microsoft 排版:Alan Wang 大家好,欢迎回到11月的 Java on Azure Tooling 的更新。在这次更新中,我们将引入对 Azure Spring Apps 和 Azure Function Apps 的远程调试支持…

MySql补充知识点

这里写自定义目录标题1、sql语句查询表结构信息(1)查询某库某表的字段、数据类型、字段注释(2)查询某库的所有表名、表注释(3)查询库下所有表名、表注释、所有字段名、数据类型、字段注释(4)查询某个表在哪个库2、MySQL操作符(1)Union(2)having、on、where的区别having、whereo…

虚拟化与云计算技术硬核内幕

这种将物理硬件分配给多个使用者的技术,叫做“时分复用”。计算机操作系统的任务调度模块,实质上提供的就是将CPU以“时分复用”的方式给不同任务使用的机制。 那么,如果在虚拟化系统中,也利用时分复用机制,将一个物理…

Pspice——Source用法的汇总

信号源(Source)的用法 库所在位置:…CAPTURE\LIBRARY\PSPICE\SOURCE.OLB 模拟信号源列表 信号源 类型 用法 适用场景 VAC/IAC 交流 电压源/电流源 VDC/IDC 直流 电压源/电流源 直流特性分析、瞬态分析 VEXP/IEXP 指数 电压…

MVCC 多版本并发控制

Multi-Version Concurrency Control 多版本并发控制,MVCC 是一种并发控制的方法, 一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存。 实现原理 放在中间件的用户进程通过tcp/ip连接到服务器上 服务器给…

ssm+Vue计算机毕业设计校园学生管理系统(程序+LW文档)

ssmVue计算机毕业设计校园学生管理系统(程序LW文档) 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技…

FENeRF: Face Editing in Neural Radiance Fields翻译

论文地址 代码地址 摘要: 以前的肖像生成方法大致分为两类:2D GAN和3D感知GAN。2D GAN可以生成高保真的肖像,但具有低的视觉一致性。3D感知GAN方法可以保持视觉一致性,但其生成的图像不具有局部可编辑性。为了克服这些限制,我们…

Java Timer(定时器)

概述: Timer是一种定时器工具,用来在一个后台线程计划执行指定任务。它可以安排任务“执行一次”或者定期“执行多次”。 然而在实际的开发过程当中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。对于这…

【AI理论学习】Graph Embedding理论介绍及5种算法演示(DeepWalk)

Graph Embedding理论介绍及5种算法演示1.图数据结构2.图表示学习3.Graph Embedding3.1 DeepWalk算法DeepWalk算法理论DeepWalk 核心代码参考资料1.图数据结构 在现实世界中,网络只是互连节点的集合。为了表示这种类型的网络,我们需要一个与之相似的数据…