并发前置知识二:多线程不安全的本质

news2024/12/23 18:29:08

一、前言

这些年,我们的cpu、内存和i/o设备都在不断迭代,不断朝着更快的方向努力。但是,在这个快速发展的过程中,有一个核心矛盾一直存在,就是这三者的速度。

  1. cpu是天上1天,内存是地上1年
  2. cpu是天上1天,io是地上10年

为了合理利用cpu的高性能,平衡这三者的速度差异,计算机系结构、操作系统、编译程序都做出了贡献,主要体现为:

  1. cpu加了缓存,以均衡与内存的速度差异
  2. 操作系统增加了进程、线程,以时分复用cpu,进而均衡cpu与i/o设备的速度差异
  3. 编译程序优化指令执行次序,使得缓存能够更加合理的利用

二、造成的问题

1.缓存导致的可见性问题

在多核cpu时代,每个cpu都有自己的缓存,cpu1对于缓存的操作对于cpu2是不可见的,所以当cpu2对某一个值处理时,是不知道别的cpu对它的更改的,所以会有可见性问题

2.线程切换带来的原子性问题

java并发程序是基于多线程的,多线程自然就涉及任务切换,比如一条 count+1=1, 至少需要三条cpu指令

  1. 指令1: 首先,需要把变量count从内存加载到CPU的寄存器
  2. 指令2: 之后,在寄存器中执行+1的操作
  3. 指令3: 最后,把结果写入到内存中(缓存机制导致可能写入的是cpu缓存而不是内存)

image.png
cpu保证的是cpu指令是原子的,但是高级语言的指令不会是原子操作。一条高级语言的操作往往对于多条cpu指令,如果想解决这种原子性的问题,大多要使用🔒。

3.编译优化带来的有序性问题

通过一个双重检查创建单例对象来说明这个编译优化带来的问题:

public class Singletion{
  static Singleton instance;
  static Singletion getInstance(){
      if (instance == null ){
          synchronized(Singleton.class){
              if(instance == null)
                  instance = new Singletion();
          }
      }
  }
}

我们理想的情况是:

  1. 线程A和线程B同时执行getInstance方法,线程A先进入获取到锁之后,然后开始创建Singleton对象,线程B后来进入,没有拿到锁,然后阻塞起来。
  2. 等线程A创建完对象,释放锁之后线程B 判断 instance== null时发现,已经创建过来,就不会再创建了

but:这里问题出现在了 newSingleton上,new Singleton会出现先释放引用,然后再分配内存的指令重排序,如果刚好在这个时候,内存还没来的分配好,就发生了线程切换,线程B 判断instance == null 为false,就返回了,但是真正去获取成员变量的时候,就会发生空指针,因为成员变量内存还没有分配好。

三、如何解决这些问题

java提供了很多关键字(sync、final、volatile)来按需禁用缓存、按需禁用编译优化。

1.解决可见性

volatile、sync这些解决可见性本质上就是通过内存屏障保证对于工作内存的修改或者读取都直接作用于主内存

2.解决原子性

volatile并不具备原子性,只是在32位机器上对于Long类型的读写保证原子性

要具备原子性,还是要有锁,要有临界区的概念,要让一组操作一起。sync里面的操作都是具有原子性的。

3.解决有序性

volatile、sync都是通过内存屏障来解决有序性的问题

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

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

相关文章

万字长文 详细讲述 计算机网络层

文章目录 网络层网络层的几个重要概念网络层的两个层面 网际协议 IP虚拟互连网络IP 地址IP 地址及其表示方法IP 地址与 MAC 地址地址解析协议 ARPIP 数据报的格式 IP层转发分组过程基于终点的转发最长前缀匹配 网际控制报文协议 ICMPICMP 报文的种类ICMP 的应用举例IPv6 的基本…

2023年全国职业院校技能大赛软件测试赛题—单元测试卷③

单元测试 一、任务要求 题目1:输入一个大写字母一个小写字母。根据输入的第一个字母和英文周几单词的第一个大写字母判断是周几,如果无法根据第一个大写字母判断,则继续根据输入的第二个小写字母进行判断,最终返回正确的英文周几…

【Redis】Redis面试热点

Redis 集群有哪些方案? 主从复制:解决了高并发问题 哨兵模式:解决了高并发,高可用问题 分片集群:解决了海量数据存储,高并发写的问题 主从复制 图示: 主从复制:单节点 Redis 并发…

python进行简单的app自动化测试(pywinauto)+ 截屏微信二维码

一、开始需要了解准备 1、安装 pip install pywinauto2、选择(后面会通过工具进行判断用哪个) 3、自动化控制进程的范围 示例 Application单进程 Desktop多进程 4、程序辅助检测工具 3中的下载连接 链接 点击放大镜拖到对应位置即可 二、简单的开始…

梦想贩卖机升级版知识付费源码,包含前后端源码,非线传,修复最新登录接口问题

梦想贩卖机升级版,变现宝吸收了资源变现类产品的许多优势,并剔除了那些无关紧要的元素,使得本产品在运营和变现能力方面实现了质的飞跃。多领域素材资源知识变现营销裂变独立版本。 支持:视频、音频、图文、文档、会员、社群、用…

yolov8n 瑞芯微RKNN和地平线Horizon芯片仿真测试部署,部署工程难度小、模型推理速度快

特别说明:参考官方开源的yolov8代码、瑞芯微官方文档、地平线的官方文档,如有侵权告知删,谢谢。 模型和完整仿真测试代码,放在github上参考链接 模型和代码。 因为之前写了几篇yolov8模型部署的博文,存在两个问题&…

【AI】AI和医疗大数据(3/3)

目录 六、AI和医疗大数据的结合案例——基于卷积神经网络CT图像检测 ——步骤: ——技术: ——案例: ——典型应用步骤详解: 第一步:数据预处理 第二步:训练集构建 第三步:预测 第四&a…

Serverless无服务

软件工程的本质复杂度和次要复杂度 本质:如何从抽象的问题,发展出具体的概念上的解决方案(业务问题) 次要:指实现它的过程(技术手段) 过去解决了的次要复杂度(提升研发效率&#…

代币中的decimal精度代表了什么

精度的意义在于允许发送小数的代币。举例,一个CAT代币合约的精度为6。那么 你拥有1个CAT就意味着合约中的balance 1 * 10^6 , 转账 0.1CAT出去的话,就需要输入 0.1*10^6 10^5。 也就时在涉及代币时,查询到的余额、转账的代币数量 都和 代币…

用通俗易懂的方式讲解大模型分布式训练并行技术:MOE并行

前面的文章中讲述了数据并行、流水线并行、张量并行、序列并行、自动并行等多种并行技术。但现在的模型越来越大,训练样本越来越多,每个样本都需要经过模型的全部计算,这就导致了训练成本的平方级增长。 而当我们希望在牺牲极少的计算效率的…

使用numpy处理图片——90度旋转

在《使用numpy处理图片——镜像翻转和旋转》一文中,我们介绍了如何将图片旋转的方法。本文将使用更简单的方法旋转图片90度。 左旋转90度 import numpy as np import PIL.Image as Imagedata np.array(Image.open(the_starry_night.jpg))# left 90 rot90LeftWith…

电子学会C/C++编程等级考试2020年12月(二级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:数组指定部分逆序重放 将一个数组中的前k项按逆序重新存放。例如,将数组8,6,5,4,1前3项逆序重放得到5,6,8,4,1。 时间限制:1000 内存限制:65536 输入 输入为两行: 第一行两个整数,以空格分隔,分别为数组元素的个数n(1 < n…

鸿蒙HarmonyOS兼容JS的类Web开发-开发指导

鸿蒙HarmonyOS兼容JS的类Web开发-开发指导 文章目录 鸿蒙HarmonyOS兼容JS的类Web开发-开发指导常用组件开发指导list开发指导创建list组件添加滚动条添加侧边索引栏实现列表折叠和展开场景示例 dialog开发指导创建dialog组件设置弹窗响应场景示例 form开发指导创建form组件实现…

一个完整的流程表单流转

1.写在前面 一个完整的流程表单审批&#xff08;起表单-->各环节审批-->回退-->重新审批-->完成&#xff09;&#xff0c;前端由Vue2jsElement UI升级为Vue3tsElement Plus&#xff0c;后端流程框架使用Flowable&#xff0c;项目参考了ruoyi-vue-pro(https://gite…

使用python读取yaml文件数据

使用python读取yaml文件&#xff1a; yaml文件数据&#xff1a;data.yaml login_data:url: http://www.baidu.comcase1:user1: password1: 12345errorText: 请输入用户名case2:user2: adminpassword2: errorText: 请输入密码case3:user3: adminpassword3: 123456errorText: 登…

视频监控设备通过onvif协议接入到视频监控平台

目 录 一、什么是onvif规范 1、onvif的定义 2、onvif的优势 二、AS-V1000监控平台对onvif的支持程度 二、通过onvif接入视频监控设备 1、onvif维护主页面 2、设备发现 3、设备验证 4、设备录入系统 5、通道配置 6、权限分配 三、对onvif设备进行…

【设计模式-6】建造者模式的实现与框架中的应用

建造者模式又被成为生成器模式&#xff0c;是一种使用频率比较低&#xff0c;相对复杂的创建型模式&#xff0c;在很多源码框架中可以看到建造者的使用场景&#xff0c;稍后我们会在本文末尾展示几个框架的使用案例。  建造者模式所构造的对象通常是比较复杂而且庞大的&#x…

C++ n皇后问题 || 深度优先搜索模版题

n− 皇后问题是指将 n 个皇后放在 nn 的国际象棋棋盘上&#xff0c;使得皇后不能相互攻击到&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n &#xff0c;请你输出所有的满足条件的棋子摆法。 输入格式 共一行&#xff0c;包含整数 n 。 …

SpringCloud 之HttpClient、HttpURLConnection、OkHttpClient切换源码

SpringCloud 之HttpClient、HttpURLConnection、OkHttpClient切换源码 HttpClient、HttpURLConnection、OkHttpClient区别切换HttpClient 源码分析总结切换HttpClient源码验证切换是否成功okHttpClient 切换源码分析总结 okHttpClient 切换源码同时开启 okHttp 与httpClient 会…

【数字人】8、EAT | 为数字人引入情感表情(ICCV2023)

论文&#xff1a;Efficient Emotional Adaptation for Audio-Driven Talking-Head Generation 代码&#xff1a;https://yuangan.github.io/eat/ 出处&#xff1a;ICCV2023 特点&#xff1a;能引入表情&#xff0c;但无法眨眼&#xff0c;需要 音频 pose 图片 同时作为输入…