码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 深入了解JUC并发(二)并发理论


    文章目录

      • 并发理论
        • Java内存模型(JMM)
          • 概念
          • JVM对Java内存模型的实现
            • 栈区和堆区
        • 重排序和数据依赖性
          • 重排序
            • 内存屏障(Memory Barrier)
          • 数据依赖性
        • as-if-serial和happens-before规则
          • as-if-serial
          • happens-before
            • happens-before规则

    并发理论

    Java内存模型(JMM)

    首先,线程之间以何种机制来交换信息,主要有两种:共享内存和消息传递。Java内存模型是 共享内存 的并发模型,线程之间主要通过读-写共享变量来完成隐式通信

    概念

    上面讲的 共享内存 模型指的就是 Java内存模型 (简称JMM):

    1. Java内存模型决定一个线程对共享变量的写入何时对另一个线程可见
    2. 线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本

    在这里插入图片描述

    图中所示,线程A与线程B之间如要通信的话,必须要经历下面2个步骤:

    1. 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去
    2. 然后,线程B到主内存中去读取线程A之前已更新过的共享变量

    JVM对Java内存模型的实现

    Java内存模型把内存分成了两部分:线程栈区和堆区,下图展示了Java内存模型在JVM中的逻辑视图:

    在这里插入图片描述

    栈区和堆区

    JVM中运行的每个线程都拥有自己的线程栈,线程栈包含了当前线程执行的方法调用相关信息,我们也把它称作调用栈。随着代码的不断执行,调用栈会不断变化

    线程栈:

    1. 当前方法的所有本地变量信息
    2. 所有原始类型(boolean,byte,short,char,int,long,float,double)的本地变量都直接保存在线程栈当中

    堆区:包含了Java应用创建的所有对象信息,不管对象是哪个线程创建的

    在这里插入图片描述

    重排序和数据依赖性

    重排序

    在执行程序时,为了提高性能,编译器和处理器会对指令做重排序

    1. 编译器优化重排序:编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
    2. 指令级并行的重排序:如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
    3. 内存系统的重排序:处理器使用缓存和读写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。
    内存屏障(Memory Barrier)

    编译器和CPU能够重排序指令,保证最终相同的结果,尝试优化性能。但是插入一条 内存屏障 告诉编译器和CPU:不管什么指令都不能和这条 内存屏障 重排序

    用volatile实现:内存屏障 所做的另外一件事是强制刷出各种 CPU缓存,如一个 写入屏障 将刷出所有之前写入缓存的数据,因此,任何CPU上的线程都能读取到这些数据的最新版本(也就是volatile,保证最新)

    数据依赖性

    • 如果两个操作访问同一个变量,其中一个为写操作,此时这两个操作之间存在数据依赖性
    • 编译器和处理器不会改变存在数据依赖性关系的两个操作的执行顺序,即不会重排序

    as-if-serial和happens-before规则

    as-if-serial

    不管怎么重排序,单线程下的执行结果不能被改变,编译器、runtime和处理器都必须遵守as-if-serial语义

    happens-before

    如果一个操作的执行结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系,这个的两个操作既可以在同一个线程,也可以在不同的两个线程中

    happens-before规则
    1. 程序顺序规则:一个线程中的每个操作,happens-before于该线程中任意的后续操作
    2. 监视器锁规则:对一个锁的解锁操作,happens-before于随后对这个锁的加锁操作
    3. volatile域规则:对一个volatile域的写操作,happens-before于任意线程后续对这个volatile域的读
    4. 传递性规则:如果 A happens-before B,且 B happens-before C,那么A happens-before C
  • 相关阅读:
    Java项目之石头剪刀布
    2022.07.04
    计算机毕业设计 基于SpringBoot的养老院管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    python数据可视化-matplotlib入门(4)-条形图和直方图
    <蓝桥杯软件赛>零基础备赛20周--第2周
    游戏数据分析必知必会
    java中BigDecimal除法运算指定小数点保留位数和取舍规则
    【深度学习】吴恩达课程笔记(一)——深度学习概论、神经网络基础
    CAN(Controller Area Network)是一种用于在汽车和工业领域中进行通信的串行总线系统(附加案例)
    【C++】C++ 类中的 this 指针用法 ① ( C++ 类中的 this 指针引入 | this 指针用法 | 代码示例 )
  • 原文地址:https://blog.csdn.net/qq_42709715/article/details/125544789
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号