并发编程_jmm部分

1. JMM 理解

前提:并发编程有3大问题,可见性、有序性、原子性。
导致可见性的原因是缓存,有序性的原因是 编译器优化。解决方法就是直接禁用缓存和编译器优化,导致程序性能堪忧。
因此合理的方案就是按需禁用缓存和编译器优化。

所以: java 内存模型针对在多线程环境下,可见性 有序性制定了一些规范,在jvm 层面 提供按需禁用缓存和编译优化的方法。具体就是使用synchronized,volatile,final三个关键字和Happens-before 规则。 解决并发编程中 的代码的有序性和可见性。

long double 32位原子性问题。

3
如果需要保证 long 和 double 在 32 位系统中原子性,需要用 volatile 修饰

load load 两个连续的读不要重排序 防止读跑上去

防止 B 的 Load 重排到 A 的 Load 之前

if(A) {
    LoadLoad
    return B
}

read(A)
LoadLoad
read(B)
  • 意义:A == true 时,再去获取 B,否则可能会由于重排导致 B 的值相对于 A 是过期的
    3

loadstore 防止连续 读写 防止写跑上去。

3

Acquire 第一个是load,防止后续的 读、写 不要重排序

同一线程内,读 操作之后的的读写,上不去,同时第一个load能读到主存中的最新值。
3

store store 连续的写 防止写跑下来

  • 防止 A 的 Store 被重排到 B 的 Store 之后
A = x
StoreStore
B = true
  • 意义:在 B 修改为 true 之前,其它线程别想看到 A 的修改
    • 有点类似于 sql 中更新后,commit 之前,其它事务不能看到这些更新(B 的赋值会触发 commit 并撤除屏障)
      3

release 防止读和写 跑下来。 ss ls

同一线程内,写操作之前的 , 读写下不来,后面的store 都能将改动的 都写入主存。
store store
load sore
防止上面的 读操作 写操作,被重排序到 写操作下面
3

store load ** 发生在线程切换时有效。 保证可见性。

sotre load 屏障 在线程切换时,保证可见性。

意义:屏障前的改动都同步到主存,屏障后的 Load 获取主存最新数据

  • 防止屏障前所有的写操作,被重排序到屏障后的任何的读操作,可以认为此 store -> load 是连续的
  • 有点类似于 git 中先 commit,再远程 poll,而且这个动作是原子的
    3

2.volatile 本质

写变量时 加 loadstore store store 屏障 和 store load 屏障

红色 蓝色是两个线程。
a

读取变量时 load load ,load store

在变量加入load load load store 屏障
3

1. 保证单一变量赋值的原子性

32 位操作系统,long double

2. 保证变量的有序性

线程内通过内存屏障保证有序,线程切换按照happen-before 有序。

partial ordering

total ordering

3. 可见性

线程切换时 ,发生了写->读,则变量可见,顺便影响普通变量可见性。
在volatile 变量 加入store load 屏障。
红色线程的写入同步到主存,然后让蓝色线程的读取,取主存中读取最新值。
3

3. Synchronization order

线程内部的一个顺序

4.happen-before 原则

在线程切换时,代码的顺序 和可见性。

表达的是,前一个线程的操作的结果 对后续线程的操作是可见的。

线程启动 和运行边界

线程1 启动线程2前对共享变量进行修改,在线程2运行时,读取共享变量一定能看到修改。
3

线程的结束 和join 的边界。

线程1 结束前,对共享变量的修改。t2线程等待t1线程的解释 join,t2也能读取到共享变量的读取。

线程的打断 和得知线程的打断。

interrupt
t1线程修改共享变量,t1线程对t2线程打断,t2线程得知打断,能够读取到共享变量的改变。
3

unlock 和lock 边界。

t1线程解锁前对共享变量的修改,t2线程加锁后,能够读取到共享变量的修改。

volatile 对变量的写 和volatile 的读 的边界

传递性

如果a hb b,
b hb c,
那么有a hb c

5. cas 原理

使用乐观锁机制,保证变量读写的原子性。
volatile+ cas 实现原子 可见 有序
volatile 搭配cas 保证 共享变量的可见性。
线程数小于cpu 核心数,乐观锁性能高。

aqs 的state 使用volatile

cas + volatile 保证 state 的最新值 和 互斥。

concurrenthashmap 懒惰初始化

有一个sizectl 属性,volatile 修饰,保证可见性。
在第一次 put 时,检查sizectl,使用cas 把 0 改成 -1, (-1,hash表正在被初始化),
其他线程来 初始化 cas 失败,不会重复创建了。

6. synchronized

有序性

3
在monitor enter 和 monitor exit 加了相应的屏障,
保证了 同步代码块 内部的代码,共享变量的读写, 不会重排序到同步代码块的外面。
强调 :
但是 在同步代码块内部还是会存在重排序的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JUC之ThreadLocal

文章目录 1 基础知识1.1 强软弱虚四种引用 2 ThreadLocal出现的好处3 ThreadLocal源码分析3.1 ThreadLocal内存泄露问题3.2 ThreadLocal为什么使用的是弱引用3.3 清扫过期的Entry 4 ThreadLocal使用建议 1 基础知识 1.1 强软弱虚四种引用 【整体结构】 【强引用】 【软引用…

初始网络原理

目录 网络发展史 独立模式 网络互连 局域网LAN 广域网WAN 网络通信基础 IP地址 端口号 认识协议 五元组 协议分层 OSI七层模型 TCP/IP五层(或四层) 网络设备所在分层 封装和分用 网络发展史 独立模式 独立模式:计算机之间相互…

【技能实训】Day01

文章目录 任务1 项目准备一、开发环境二、系统简介三、项目创建 任务2【任务2.1】菜单项设计及其测试【任务2.2】使用数组存储采集的数据【任务2.3】控制显示采集的数据 任务1 项目准备 一、开发环境 1.JDK8下载及其环境变量配置(JDK8以上版本) 2.IDE :Eclipse 或…

应用层:万维网WWW

1.万维网WWW 笔记来源: 湖科大教书匠:应用层概述 湖科大教书匠:万维网WWW 声明:该学习笔记来自湖科大教书匠,笔记仅做学习参考 浏览器最重要的部分是渲染引擎,也就是浏览器内核。负责对网页内容进行解析和…

postgresql 数据库 索引 介绍

postgresql 数据库 索引 介绍 文章目录 postgresql 数据库 索引 介绍前言一 什么是索引?二 简介三 索引的种类B-treeHash索引GiST索引GIN 索引BRIN 索引SP-GiST索引 CREATE INDEX1.大纲2.描述3. 参数UNIQUECONCURRENTLYIF NOT EXISTSINCLUDEnameONLYmethodcolumn_na…

Vue3:在 VSCode 中如何成功安装 Mockjs 及成功引入 Mock 的详细过程

Ⅰ、Mock 简介: 1、什么是 Mock? 其一、Mock 的解释一: Mock 服务是指在测试过程中对于某些复杂(或者不太好构造)的对象,用一个虚拟的对象替代它;对于前端来说,就是后台数据还没有…

RS485或RS232转ETHERCAT连接安川ethercat总线伺服

最近,生产管理设备中经常会遇到两种协议不相同的情况,这严重阻碍了设备之间的通讯,串口设备的数据不能直接传输给ETHERCAT。这可怎么办呢? 别担心,远创智控YC-ECT-RS485/232来了!这是一款自主研发的ETHER…

数据结构第一章 绪论——走进数据的世界

名人说:唯一可以确定的是,明天会使我们所有人大吃一惊。——阿尔文托夫勒 本篇笔记整理:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) ✔ 课件资料及视频课程学习:王道 数据结构&#xff08…

Linux 网络延迟排查方法详解

概要 在 Linux 服务器中,可以通过内核调优、DPDK 以及 XDP 等多种方式提高服务器的抗攻击能力,降低 DDoS 对正常服务的影响。在应用程序中,可以使用各级缓存、WAF、CDN 等来缓解 DDoS 对应用程序的影响。 但是需要注意的是,如果 …

Lingo优化软件初步

一、Lingo软件介绍 1、lingo软件的简单介绍 美国芝加哥大学的Linus Schrage教授于1980年左右开发的专门用于求解最优化问题的软件包,后经多年完善与扩充,并成立了LINDO系统公司进行商业运作取得巨大成功。根据 LINDO公司主页(http://www.li…

六、HAL_Timer的PWM功能

1、开发环境 (1)Keil MDK: V5.38.0.0 (2)STM32CubeMX: V6.8.1 (3)MCU: STM32F407XGT6 2、PWM简介 2.1、什么是PWM (1)PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。 (2)P…

蓝奥声开发高性价比智能wifi插座进军智能家居

关键词:智能家居、家用插座、WiFi插座、高性价比插座 智能硬件的大潮袭来让智能家居这一并不新鲜的概念再次火热起来,关于智能家居的各种场景的描述给了我们很大的想象空间,然而落到实处真正开始走进生活时却又显得那么骨感,一时间…

(30)精准降落和悬停(IRLock)

文章目录 30.1 概述 30.2 哪里可以买到 30.3 连接到自动驾驶仪 30.4 安装到框架上 30.5 通过任务规划器进行设置 30.6 飞行和测试 30.1 概述 Copter 支持使用 IR-LOCK 传感器(IR-LOCK sensor)和声纳或激光雷达(sonar or lidar)进行精确着陆。使用该系统,当飞行…

基于深度学习的目标检测的介绍(Introduction to object detection with deep learning)

物体检测的应用已经深入到我们的日常生活中,包括安全、自动车辆系统等。对象检测模型输入视觉效果(图像或视频),并在每个相应对象周围输出带有标记的版本。这说起来容易做起来难,因为目标检测模型需要考虑复杂的算法和数据集,这些…

内存的五大分区

一些套话 一个由C/C编译的程序占用的内存分为以下几个部分:栈区,堆区,全局区(静态区),文字常量区,代码区 在执行一个C/C 程序时,此程序拥有唯一的“内存四区”(栈区&…

00-C++-ccache使用

ccache使用 前言ccache是什么ccache使用 前言 在编译大型C项目代码时编译时间比较长,那么可以使用ccache来加速代码的编译,一起来学习吧。 ccache是什么 ccache是一个编译器缓存。它通过缓存以前编译的结果并检测何时再次进行相同的编译来加快重新编译…

聊聊不同集群的微服务如何通过feign调用

前言 之前业务部门的某项目微服务调用关系如下图 后因业务改造需要,该项目需要将服务A部署到另外一个集群,但服务A仍然需要能调用到服务B,调用关系如下图 之前调用方式是负责服务B的开发团队提供相应的feign客户端包给到服务A开发团队&…

k8s 第一篇 基础知识

一 k8s 1.1 概念 k8s 是一个能让应用部署到容器中,实现自动部署和管理更加高效 自能化的平台。 也就是说通过k8s,能够进行应用的自动化部署和扩容。 1.2 集群的架构流程 1.3 k8s的核心概念 1.4 k8s 集群规划 从第6集开始看

基于OpenCV 实现车牌号码识别--附免费源码

在本教程中,您将学习如何使用 OpenCV 和 EasyOCR 包自动执行车牌/车牌识别 (LPR/NPR)。 EasyOCR是一个开源 Python 包,用于执行光学字符识别 - OCR(从图像中提取文本)。 该软件包非常易于使用,在撰写本文时,它支持 80 多种语言,包括中文、阿拉伯语、法语、英语、西里尔…

MySQL-SQL全部锁详解(上)

​♥️作者:小刘在C站 ♥️个人主页: 小刘主页 ♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生! ♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏&#x…