Java并发编程—java内存模型1

news2024/12/25 12:47:34

文章目录

  • Java内存模型的基础
    • 并发编程模型的两个关键性问题
      • 1、线程之间如何通信?(问题1)
      • 2、进程之间如何通信?(问题2)
    • 线程间通信机制:共享内存、消息传递
      • 1、共享内存
      • 2、消息传递
    • java内存模型抽象结构
    • 指令重排序
    • 并发编程模型的分类
    • happens-before

——————————————————————————————————

Java内存模型的基础

并发编程模型的两个关键性问题

1、线程之间如何通信?(问题1)

  • t1改的东西,t2能够读到它
  • 两个线程能够操作同一个地方,一个线程修改了变量,另一个线程能够读到

2、进程之间如何通信?(问题2)

  • 进程间通信是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息。
  • 这使得一个程序能够在同一时间里处理许多用户的要求。
  • 因为即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行,进程之间必须互相通话。
  • —>IPC接口就提供了这种可能性。
  • 每个IPC方法均有它自己的优点和局限性,一般,对于单个程序而言使用所有的IPC方法是不常见的。
    进程间通信的8种方法:
    1)无名管道通信
    2)高级管道通信
    3)有名管道通信
    4)消息队列通信
    5)信号量通信
    6)信号
    7)共享内存通信
    8)套接字通信
    注:
  • 线程有的通信方式进程不一定有
  • 进程有的通信方式线程一定有
  • 因为进程是由线程组成的

线程间通信机制:共享内存、消息传递

1、共享内存

  • 同一个进程里的线程,能共享堆里面的对象(共享空间);
  • 不同进程之间,内存不共享
  • 有自己主方法的都是一个进程,有自己的独立空间,空间不共享;
    • t1进程不能读取t2进程的变量

2、消息传递

——》通过方法调用

java内存模型抽象结构

  • 每个线程都有一个本地的副本
  • 线程a要想给线程b通信依托共享变量
    • 如果线程A与线程B之间要通信的话,必须要经历下面2个步骤。
      • 1)线程A把本地内存A中更新过的共享变量刷新到主内存中去。
      • 2)线程B到主内存中去读取线程A之前已更新过的共享变量。
        在这里插入图片描述
        静态的句柄在方法区,静态的值伴随句柄存在
        静态引用类型的值在堆中

指令重排序

  • 依托于计算机组成原理的流水线技术,是由流水线技术导致的
  • 为了提高性能,编译器和处理器常常会对指令做重排序:

重排序分为三种:

  • 编译器优化的重排序
    • 编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序
  • 指令级并行的重排序
    • 现代处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
  • 内存系统的重排序
    • 由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。
      在这里插入图片描述

并发编程模型的分类

讲的重排序导致的结果

  • 两行代码——》a = 1; b = 2;有可能是后面的代码先执行(指令重排序)
  • 一行代码——》Object a = new Object();可能是先开辟空间再创建对象。一行代码的执行顺序也有可能是乱序的(比如先有了对象的地址,对象还不存在)

两个线程共同操作a,b,x,y
在这里插入图片描述
结果x=y=0出现的原因是x=b;y=a;先执行了。
读写操作:

  • a = b;等号右侧是变量为读操作
  • a = 8;等号右侧是值为写操作
    在这里插入图片描述
    读写四种组合:
  • (Load-Load)读-读:a = b; c = d;
  • (Load-Store)读-写:a = b; e = 9;
  • (Store-Store)写-写:w = 8; q = 5;
  • (Store-Load)写-读:r = 8; h = g;

认为:有数据依赖不能重排序,其他时候都能重排序。(有数据依赖的情况=> a=2; b=a;)
内存屏障类型:
通过某种手段防止指令重排序——>保障写后读
保障写后读就是保障多线程下的安全(基于其他线程计算的结果上去计算)

happens-before

在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。

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

两个操作之间具有happens-before关系,并不意味着前一个操作必须要在后一个操作之前执行!
【happens-before仅仅要求前一个操作(执行的结果)对后一个操作可见,且前一个操作按顺序排在第二个操作之前】

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

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

相关文章

资料库的webrtc文件传输

一、一个看似简单的事情往往不简单 一个简单的事情往往会倾注你的心血,也许你看到很简单往往其实没那么简单;其实想想今年业余时间的大把代码,真正能成品的好像并不多。 马上年底了,写下这篇文章。每一行程序就像写小说一样&…

Egg 1. 快速开始 Quick Start 1.3 一步步 Step by Step 1.3.1 初始化 1.3.2 创建控制器

Egg Egg 本文仅用于学习记录,不存在任何商业用途,如侵删 文章目录Egg1. 快速开始 Quick Start1.3 一步步 Step by Step1.3.1 初始化1.3.2 创建控制器1. 快速开始 Quick Start 1.3 一步步 Step by Step 之前我们直接使用 npm init egg,选择了…

# 智慧社区管理系统-基础管理-04业主管理

一后端 1entity package com.woniu.community.entity;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data AllArgsConstructor NoArgsConstructor public class Owner {private int id;private String userName;private String …

Linux I2C驱动框架, 调试神奇I2C-Tools介绍

1. IIC协议 2. Linux的I2C体系结构分为3个组成部分: I2C核心( i2c-core.c ):   I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法、I2C通信方法(”algorithm”)、与具体适配器无关的代码、探测设备、检测设备地址的上层代码等。 …

在线PDF查看器和PDF编辑器:GrapeCity Documents PDF (GcPdf)

跨平台 JavaScript PDF 查看器 使用我们的 JavaScript PDF 查看器在网络上阅读和编辑 PDF。跨浏览器和框架打开和打印。GrapeCity Documents PDF (GcPdf) 全功能的 JavaScript PDF 查看器和 PDF 编辑器 适用于所有现代浏览器和框架,包括 Edge、Chrome、Firefox、Op…

UML类图中 前缀符号 + - # ~ 的含义

UML类图中有各种符号,新手看着一脸懵逼,今天我就来讲一下各个符号到底是啥意思。 其实这些符号都是在描述类属性的可见性: UML中,可见性分为4级 1、public public 公用的用 前缀表示 ,该属性对所有类可见 2、prote…

算法篇-----回溯1

文章目录什么是回溯呢?力扣690-----员工的重要性(中等)力扣733-----图像渲染(简单)力扣463-----岛屿的周长(简单)力扣130------被围绕的区域(中等)力扣17--------电话号码的组合 &am…

kafka-consumer-offset位移

目录 1 offset的默认维护位置 1.1 消费offset案例 2 自动提交offset 3 手动提交offset 3.1 原理 3.2 代码示例 3.2.1 同步提交 3.2.2 异步提交(生产常用) 4 指定offset消费 5 指定时间消费 6 漏消费和重复消费分析 6.1 重复消费 6.2 漏消费 6.3 消费者事务 7 数据…

高通开发系列 - ALSA声卡驱动中tinymix返回时间过慢

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 问题背景问题分析验证第一个猜测验证第二个猜测问题原因解决方案问题背景 我们一个高通平台上出现一个问题: tingmix命令需要几秒钟…

一文带你深入理解Linux端口重用这一特性

【好文推荐】 需要多久才能看完linux内核源码? 概述Linux内核驱动之GPIO子系统API接口 一篇长文叙述Linux内核虚拟地址空间的基本概括 轻松学会Linux下查看内存频率,内核函数,cpu频率 大家好,我是Linux吴彦祖! 开篇我先考大家一个小问题&…

Golang Map 基本原理

Go 语言中的 map 即哈希表。哈希表把元素分到多个桶里,每个桶里最多放8个元素。在访问元素时,首先用哈希算法根据 key 和哈希表种子获得哈希值(暂将其命名为 h),然后利用 h 的低 bbb 位得到桶的序号。其中桶的个数为 2b2^b2b 个,是…

乐趣国学—品读“富润屋,德润身。”中的智慧

✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 ✨当前专栏:国学周更-心性养成之路 …

java 基于 SpringMVC+Mybaties+ easyUI 快递公司管理系统 的 设计与实现

一.项目介绍 本系统 角色 权限 动态配置 默认配置了三种 第一种: 超级管理员 第二种: 运输公司 第三种: 订单跟踪人员 超级管理员拥有所有权限,包括车子、路线、订单、是否送达以及交易的统计报表 运输公司:车辆管理权…

使用 Python 和 Streamlit 创建一个很棒的 Web 应用程序

“我们如何制作一个机器学习脚本并将其转换为一个尽可能简单的应用程序,让它基本上感觉像是一个脚本练习?” — Adrien Treuille(Streamlit 的发明者) Web 应用程序是显示数据科学或机器学习项目结果的好方法。从头开始开发 Web 应用程序需要大量时间、精力和技术技能。另一…

世界杯海信再出圈,三星:“谈不上愉悦”

作者 | 曾响铃 文 | 响铃说 本届世界杯作为第一次在北半球冬季举行的世界杯,给全世界球迷带去了一次全新体验。且随着赛程的推进,更多的“惊喜”也一一浮现。 其一便是超多的爆冷,虽然没有具体统计,但此次应该是近几届爆冷最多…

[激光原理与应用-32]:典型激光器 -4- 半导体泵浦固体激光器

目录 第1章 概述 1.1 什么是半导体泵浦固体激光器 1.2 优势 1.3 典型的波长 第2章 半导体泵浦固体激光器的种类 2.1 端面泵浦固体激光器 2.2 侧面泵浦固体激光器 第1章 概述 1.1 什么是半导体泵浦固体激光器 半导体泵浦固体激光器(Diode Pump Solid State …

Python函数

一、函数介绍 函数:是组织好的,可重复使用的,用来实现特定功能的代码段。 使用函数的好处是: 将功能封装在函数内,可供随时随地重复利用提高代码的复用性,减少重复代码,提高开发效率二、函数…

学习python第一天

关于Python的数据类型 Python数据类型包括: 数字类型,字符类型,布尔类型,空类型,列表类型,元组类型,字典类型 1、数字类型 包括:整型int 浮点型float(有小数位的都是是浮点型) 注…

代码随想录刷题|LeetCode 1143.最长公共子序列 1035.不相交的线 53. 最大子序和 动态规划

目录 1143.最长公共子序列 思路 1、确定dp数组 2、确定递推公式 3、dp数组初始化 4、遍历顺序 5、推导dp数组 最长公共子序列 1035.不相交的线 思路 不相交的线 53. 最大子序和 思路 最大子序列 动态规划 贪心算法 1143.最长公共子序列 题目链接:力扣 思路 不知道…

你在终端启动的进程,最后都是什么下场?(下)

你在终端启动的进程,最后都是什么下场?(下) 在上期文章你在终端启动的进程,最后都是什么下场?(上)当中我们介绍了前台进程最终结束的几种情况,在本篇文章当中主要给大家…