当前位置: 首页 > news >正文

初窥Java内存模型(JMM)

《Java并发编程的艺术》书籍

在并发编程中存在两个问题:

  1. 线程之间如何通信
  2. 线程之间如何同步

一、JMM抽象结构

用来控制多线程之间的通信,可见性、有序性、原子性。
在这里插入图片描述

线程A如何与线程B进行通信

线程之间并没有直接通信通道,如图所示要想实现通信需经历:
1)将本地内存A中更新的变量刷新到主内存当中
2)线程B到主内存读取

二、重排序

为什么会进行重排序?简单来说就是提高性能。
有三种类型
1)编译器优化重排序
2)指令级并行的重排序
3)内存系统的重排序

1、重排序带来的问题

在多线程当中重排序可能会改变程序的执行结果,通过在生成指令序列时,插入特定类型的内存屏障指令来禁止重排序。

1.1内存屏障类型

在这里插入图片描述

1.2happens-before

在Java并发编程艺术这本书中写到,happens-before的概念是用来阐述操作之间的内存可见性。
在这里插入图片描述

2、数据依赖关系与控制依赖关系

2.1 什么是数据依赖关系

如果两个操作访问同一个变量,这两个操作中有一个为写操作,此时这两个操作就存在数据依赖关系。有三种类型,写后读、写后写、读后写。在单线程中执行时重排序会遵守数据依赖,编译器和处理器不会改变存在数据依赖关系的两个操作之间的执行顺序。

2.2 什么是控制依赖关系

在判断语句当中例如下列伪代码中,操作1和操作2之间存在着数据控制依赖关系。当存在控制依赖关系时,会影响指令序列执行的并行度。因此编译器和处理器会采用猜测执行来克服控制相关性对并行度的影响。具体来说,处理器可以提取读取和计算i*i,然后临时保存到一个名为重排序缓冲(Record Buffer,ROB)的硬件缓存中,当条件判断为真是,写入到a中。

if(flag){//操作1
a = i*i;//操作2
}

相关文章:

  • 精益数据分析(24/126):聚焦第一关键指标,驱动创业成功
  • 边界凸台建模与实例
  • PGSql查看表结构以及注释信息
  • NAT穿透
  • 通过API接口在自己的独立站系统上架商品信息。(实战案例)
  • 【Java学习笔记】冒泡排序
  • NEGATIVE LABEL GUIDED OOD DETECTION WITH PRETRAINED VISION-LANGUAGE MODELS
  • WHAT - 前端开发书单推荐
  • 【vue】【element-plus】 el-date-picker使用cell-class-name进行标记,type=year不生效解决方法
  • DeepSeek回答过于笼统,提示词如何优化
  • RK3562/3588 系列之0—NPU基础概念
  • 高防IP+CDN组合:电商大促的“双保险”防护方案
  • 常见网络安全攻击类型深度剖析(二):SQL注入攻击——原理、漏洞利用演示与代码加固方法
  • linux系统问题杂谈
  • 六个能够白嫖学习资料的网站
  • Spring MVC 数据绑定利器:深入理解 @InitBinder
  • 猿人学题库13题—动态css字体加密 记录
  • 深入理解指针 (1)
  • Unity 打包后 无阴影 阴影不显示
  • Hi3516CV608 超高清智慧视觉 SoC 芯片 可提供开发资料
  • 对外投资增长、消费市场持续升温,中国经济砥砺前行
  • 精准滴灌“种企业”,苏南强县常熟新的进阶密码
  • 还山记——走进山水、感受山水艺术的魅力
  • 云南大理州洱源县发生4.8级地震,震源深度10千米
  • 金湘军辞去山西省省长职务
  • 瞭望:高校大门要向公众打开,不能让“一关了之”成为常态