IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 并发基础之Java内存模型、指令重排与数据正确性 -> 正文阅读

[数据结构与算法]并发基础之Java内存模型、指令重排与数据正确性

在不改变程序执行结果的前提下,尽可能提高并行度。

Java 内存模型

JMM 就是 Java 内存模型,由于 Java 默认支持多线程操作,每个线程中都有自己的缓存,即下图中的本地内存(本地内存并不真实存在)。

JMM 通过控制主内存与每个线程的本地内存之间的交互,实现内存可见性的保证。

JMM

指令重排

重排序分为三种类型,分别为编译器优化的重排序、指令级并行的重排序和内存系统的重排序。只有第一种属于编译器重排序,剩下的都为处理器重排序。对于编译器,JMM 的编译器重排序规则会禁止特定类型的编译器重排序。对于处理器排序,JMM 的处理器重排序规则会要求 Java 编译器在生成指令时,插入特定类型内存屏障指令来禁止特定类型的处理器重排序。

数据正确性

并发编程最重要的核心就是数据正确,JMM 一定程度上保证了数据可见性,内存屏障又保证了指令执行顺序的正确性,这一切都是为了最后的数据正确。

数据依赖性

如果两个操作访问同一个变量,且这两个操作中又有一个为写操作,此时这两个操作之间就存在数据依赖性。分为 写后读、写后写和读后写三种情况。

如果对这三种情况进行重排序,执行结果就会出现错误。编译器和处理器在重排序时会遵守数据依赖性。但不同处理器和不同线程之间的数据依赖性不被保护。

as-if-serial 语义:不管如何重排序,(单线程)程序的执行结果不能被改变。编译器、处理器都遵守 as-if-serial 语义。

重排序对多线程的影响

当编译器和处理器对代码进行重排序时,可能会导致执行结果错误。

	class ReorderExample {
	    int a = 0;
	    boolean flag = false;
	    
		public void writer() {
			a = 1;       // 1
			flag = true; // 2
		}
	
		public void reader() {
		    if(flag) {         // 3
		        int i = a * a; // 4
		    }
		}
	}

在多线程场景下,进行重排序后,线程 A 先执行操作 2,线程 B 正常执行的情况下,线程 B 中的 i 的结果就为 0,多线程程序的语义被重排序破坏了。

操作依赖性

上面代码中,操作 3 和操作 4 存在控制依赖关系。当代码存在控制依赖关系时,会影响执行序列执行的并行度。编译器和处理器会采取猜测(Speculation)执行来克服控制相关性对并行度影响。以处理器的猜测执行为例,执行线程 B 的处理器可以提前读取并计算 a*a,然后把计算结果临时保存到名为重排序缓冲(Reorder Buffer,ROB)的硬件缓存中。当判断条件为真时,再把计算记过写入变量 i 中。

顺序一致性

顺序一致性模型是理想化的参考模型,有以下两点特性:

  • 一个线程中的所有操作必须按照程序的顺序来执行。
  • 无论程序是否同步,所有线程都只能看到一个单一的操作执行顺序(即所有线程所看到的操作执行顺序一致)。在顺序一致性内存模型中,每个操作必须原子执行且立刻对所有线程可见。

顺序一致性模型一种执行效果
但 JMM 中无法保证。未同步程序在 JMM 中不但整体的执行顺序是无序的,而且所有线程看到的操作执行顺序也可能不一致。

正确的多线程同步程序的执行将具有顺序一致性(程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同)。

JMM 对数据安全性的保证

JMM 中在获取锁和释放锁的临界区内,可以进行重排序,但锁之间无法重排序。

对于未同步或未正确同步的多线程程序,JMM 只提供最小安全性:线程执行时读取到的值,要么是之前某个线程写入的值,要么是默认值。JMM 保证线程读操作读取到的值不会无中生有。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-27 11:02:06  更:2022-02-27 11:03:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 15:35:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码