并发编程实战15-重排序、happens-before

2024-01-24 15:38

本文主要是介绍并发编程实战15-重排序、happens-before,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 指令重排序
    为了优化CPU的运行效率,在条件允许的情况下,直接运行当前有能力立即执行的后续指令,避开获取下一条指令所需数据时造成的等待3。通过乱序执行的技术,处理器可以大大提高执行效率。
    比如:对于如下代码
int a = 10 // 1 
int b = 100 // 2
int c = a // 3

实际的执行过程可能会是:1-3-2,而不是:1-2-3;因为第一步获取a的值后,第三部仍然需要使用,此时,由于第二步并不会干扰单线程下程序了逻辑,将会直接执行3,再执行2.避免二次读取a值。(只是说明可能的原理,例子并不一定正确)

  • 数据依赖性(as-if-serial)

    • As-if-serial语义的意思是,所有的动作(Action)5都可以为了优化而被重排序,但是必须保证它们重排序后的结果和程序代码本身的应有结果是一致的。
    • 即如果后续逻辑计算需要依赖之前的某个值a,那么a这个值的计算步骤不能跳过。如上代码:第3步,c的值需要使用a,所以不能跳过1直接执行3
  • happens-before 规则
    语义:如果A先发生于B,那么A所做的所有改变都能被B看到
    Happens-before是用来指定两个操作之间的执行顺序。提供跨线程的内存可见性。在Java内存模型中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必然存在happens-before关系。

遵循的规则:
* 程序顺序规则:一个线程中的每个操作,happens- before 于该线程中的任意后续操作。
* 监视器锁规则:对一个监视器锁的解锁,happens- before 于随后对这个监视器锁的加锁。
* volatile变量规则:对一个volatile域的写,happens- before 于任意后续对这个volatile域的读。
* 传递性:如果A happens- before B,且B happens- before C,那么A happens- before C。

  • 锁和volatile的内存语义:(JMM)

    • 锁的获取:首先清空当前线程value内存,从主存中获取最新值;锁的释放:将当前线程内存value刷新到主内存
    • volatile的读写与锁的获取和释放对应,原理类似
  • final域的重排序规则
    对于final域,编译器和处理器要遵守两个重排序规则

1> 在构造函数内对一个final域的写入,与随后把这个构造函数的引用赋值给一个引用变量,两个操作不能重排序
2> 初次读一个包含final域对象的引用,和随后初次读这个final域,这两个操作不能重排序

美团点评博客-Java内存访问重排序的研究
深入理解Java内存模型(五)——锁
java多线程学习(九)final的内存语义

这篇关于并发编程实战15-重排序、happens-before的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/640152

相关文章

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程

《在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程》本文介绍了在Java中使用ModelMapper库简化Shapefile属性转JavaBean的过程,对比... 目录前言一、原始的处理办法1、使用Set方法来转换2、使用构造方法转换二、基于ModelMapper

Java实战之自助进行多张图片合成拼接

《Java实战之自助进行多张图片合成拼接》在当今数字化时代,图像处理技术在各个领域都发挥着至关重要的作用,本文为大家详细介绍了如何使用Java实现多张图片合成拼接,需要的可以了解下... 目录前言一、图片合成需求描述二、图片合成设计与实现1、编程语言2、基础数据准备3、图片合成流程4、图片合成实现三、总结前

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

nginx-rtmp-module构建流媒体直播服务器实战指南

《nginx-rtmp-module构建流媒体直播服务器实战指南》本文主要介绍了nginx-rtmp-module构建流媒体直播服务器实战指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. RTMP协议介绍与应用RTMP协议的原理RTMP协议的应用RTMP与现代流媒体技术的关系2

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

Golang操作DuckDB实战案例分享

《Golang操作DuckDB实战案例分享》DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性... 目录DuckDB的主要优点环境准备初始化表和数据查询单行或多行错误处理和事务完整代码最后总结Duck