当前位置: 首页 > news >正文

12 原子性|可见性|有序性|JMM内存模型

1 并发三大特性

1.1 原子性

        一个或多个操作,要么全部执行,要么全部不执行。Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,但不采取任何原子性保障措施的自增操作不是原子性的,如:i++

public class AtomicTest {static int count = 0;public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 10; i++) {new Thread(()->{for (int j = 0; j < 1000; j++) {count++;}}).start();}Thread.sleep(2000);System.out.println(count);}
}

         上述结果每次执行都不一致,说明发生了线程安全问题

如何保证原子性?

        sychronized、lock锁、CAS(AtomicInteger)

1.2 可见性

        多个线程访问同一变量,一个线程对其进行修改,其它线程能及时感知

如何保证可见性?

        volatile、内存屏障、sychronized、lock锁

1.3 有序性

        程序执行的顺序按代码先后顺序执行(为了提升性能,编译器和处理器常常会对指令做重排序,这就可能引发有序性问题)

        Java有序性依赖内存屏障

如何保证有序性?

        volatile、内存屏障、sychronized、lock锁

2 Java内存模型JMM

        并发编程需解决的问题:

                1 多线程间如何通信(线程间以何种机制交换数据)

                2 多线程间如何同步(不同线程间操作发生的相对顺序)

2.1 JMM的抽象结构

        JMM决定一个线程对共享变量的写入何时对另一个线程可见

        JMM定义了线程和主存之间的抽象关系

                1 共享变量存在主存

                2 每个线程又有自己私有的本地内存

                3 本地内存存共享变量的副本

                4 线程对共享变量的所有操作都必须在本地内存中进行,不能直接读取主存

         线程A和线程B要通信的话,必须经历以下两个步骤:

                线程A把本地内存A更新过的共享变量更新到主内存

                线程B到主内存读取线程A更新过的共享变量

        注:线程A无法直接访问线程B的工作内存,线程间通信必须经过主存

2.2 主内存与工作内存交互协议

        八大原子操作:

                lock:作用于主内存,把一个变量标识为线程独占状态(主内存)

                unlock:释放主内存独占状态的变量(主内存)

                read:主内存变量传输到工作线程中(主内存)

                load:将read操作得到的变量放入工作内存的变量副本中(工作内存)

                use:工作内存中的变量传递给执行引擎(工作内存)

                assgin:从存储引擎得到的值,赋值给工作内存的变量(工作内存)

                store:工作内存的一个变量值传到主内存(工作内存)

                write:将store操作从工作内存的变量值放到主内存变量(主内存)

        八大原子操作必须满足的规则

                1 把一个变量从主存复制到工作内存,必须顺序地按照read和load操作;把变量从工作内存同步回主存中,必须顺序地按store和write操作

                2 不允许 read load store write操作单独出现

                3 不允许一个线程丢弃assgin,变量在内存中改变之后必须同步到主存

                4 不允许一个线程未发生assgin就从工作内存同步到主存

                5 一个新的变量只能在主存中诞生,不允许在工作内存中使用一个未被初始化的变量

                6 一个变量同一时刻只允许一个线程进行lock,但可以被同一线程重复执行多次,但也需执行相同次数的unlock操作

                7 若对一个变量执行lock操作,会清空工作内存中此变量的值(执行引擎使用这个变量必须重新load或assign

                8 不允许unlock一个未被lock的变量

                9 对一个变量执行unlock之前,必须先把该变量同步到主内存中(执行store和write)

可见性问题的产生:

        线程B对变量flag的修改,并不会让线程A感知,只有当线程B对主存共享变量flag进行lock时,线程A才会重新去主存中获取

Java中可见性底层的两种实现方式:

        1 内存屏障(sychronized、Thread.sleep(10)、volatile)

        2 CPU上下文切换(Thread.yield()、Thread.sleep())

2.3 锁的内存语义

        锁释放和释放锁的内存语义:

                线程获取锁时:JMM把该线程对应的本地内存置为无效

                线程获取锁时:JMM把该线程对应的本地内存中变量刷新到主存中

        sychronized关键字的作用是确保多个线程访问共享资源时的互斥性和可见性;在获取锁之前,线程会将共享变量的最新值从主存 -> 工作内存释放锁后会将修改的值刷到主存中,保证可见性

2.4 volatile内存语义

2.4.1 volatile写的语义

        当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主存中

public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 10; i++) {new Thread(() -> {for (int j = 0; j < 10000; j++) {count++;  //static volatile int count = 0;}}).start();}Thread.sleep(10000);System.out.println(count);
}

        上述结果会有所不同,原因:当变量被use到执行引擎中时,volatile并不能改变执行引擎中的值,当变量在执行引擎assign回工作内存中时,会发生覆盖

2.4.2 volatile读的语义

        当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,需要从主存中读取共享变量(volatile读能保证每次读都是最新的数据)

2.4.3 volatile内存语义实现原理

        

相关文章:

12 原子性|可见性|有序性|JMM内存模型

1 并发三大特性 1.1 原子性 一个或多个操作&#xff0c;要么全部执行&#xff0c;要么全部不执行。Java中&#xff0c;对基本数据类型的变量的读取和赋值操作是原子性操作&#xff0c;但不采取任何原子性保障措施的自增操作不是原子性的&#xff0c;如&#xff1a;i public c…...

pytorch代码复现1(基础知识)

创建矩阵 全零矩阵 In [4]: import torch torch.__version__ xtorch.empty(5,3) xOut[4]: tensor([[0.0000e00, 0.0000e00, 4.6430e-23],[1.4013e-45, 1.2612e-44, 0.0000e00],[3.5733e-43, 0.0000e00, 0.0000e00],[0.0000e00, 0.0000e00, 0.0000e00],[0.0000e00, 0.0000e00, 0…...

PostGreSQL模式schema

问题引入 之前在做数据库设计时&#xff0c;经常会忽略schema模式&#xff0c;直接在数据库下的public模式下建立各类数据表。如果数据表命名不够规范&#xff0c;后期寻找某张表时就会比较麻烦。通过 所幸&#xff0c;PostgreSQL 的模式schema管理&#xff0c;可以对这个问题…...

大厂面试题-什么是JVM

JVM全称是Java虚拟机&#xff0c;在聊什么是JVM之前&#xff0c;我们不妨看⼀下这张图。 从这张图中可以看出JVM所处的位置&#xff0c;同时也能看出它两个作用&#xff1a; 1、运⾏并管理Java源码⽂件所⽣成的Class⽂件&#xff0c; 2、在不同的操作系统上安装不同的JVM&#…...

rest参数

Rest参数是ES6中新增的一个语法特性&#xff0c;也称为剩余参数。其语法形式为三个点&#xff08;...&#xff09;加上一个名称&#xff0c;用于表示函数的参数个数不确定&#xff0c;可以将多余的参数收集到一个数组中。Rest参数只能作为最后一个参数出现&#xff0c;且一个函…...

Hadoop3.0大数据处理学习3(MapReduce原理分析、日志归集、序列化机制、Yarn资源调度器)

MapReduce原理分析 什么是MapReduce 前言&#xff1a;如果想知道一堆牌中有多少张红桃&#xff0c;直接的方式是一张张的检查&#xff0c;并数出有多少张红桃。 而MapReduce的方法是&#xff0c;给所有的节点分配这堆牌&#xff0c;让每个节点计算自己手中有几张是红桃&#…...

JS DataTable中导出PDF中文乱码

JS DataTable中导出PDF中文乱码 文章目录 JS DataTable中导出PDF中文乱码一. 问题二. 原因三. vfs_fonts.js四. pdfmake.js五. 解决六.参考资料 一. 问题 二. 原因 DataTable使用pdfmake&#xff0c;pdfmake默认字体为Roboto&#xff0c;不支持中文字体。添加自己的字体&#…...

代码签名证书续费

代码签名证书的有效周期是1-3年&#xff0c;这种情况下证书到期了就要重新申请办理&#xff0c;最开始同样的申请验证步骤还要再走一遍&#xff0c;尤其是Ukey还是要CA机构重新颁发&#xff0c;还是要等待快递配送。OV代码签名证书、EV代码签名证书目前行业内统一采取Ukey存储&…...

机器学习之ROC与AUC

文章目录 定义ROC曲线&#xff1a;AUC&#xff08;Area Under the ROC Curve&#xff09;&#xff1a; 定义 ROC&#xff08;Receiver Operating Characteristic&#xff09;曲线和AUC&#xff08;Area Under the ROC Curve&#xff09;是用于评估二分类模型性能的重要工具。 …...

实用篇-Eureka注册中心

一、提供者与消费者 服务提供者&#xff1a;一次业务中&#xff0c;被其他微服务调用的服务。(提供接口给其他微服务) 服务消费者&#xff1a;一次业务中&#xff0c;调用其他微服务的服务。(调用其他微服务提供的接口) 例如前面的案例中&#xff0c;order-service微服务是服…...

基于springboot实现篮球竞赛预约平台管理系统项目【项目源码+论文说明】

基于springboot实现篮球竞赛预约平台管理系统演示 摘要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;篮球竞赛预约平台也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&…...

OpenHarmony docker环境搭建所见的问题和解决

【摘要】OpenHarmony docker环境搭建需要一台安装Ubuntu的虚拟机&#xff0c;并且虚拟机中需要有VScode。 整个搭建流程请参考这篇博客&#xff1a;OpenHarmony docker环境搭建-云社区-华为云 (huaweicloud.com) 上篇博主是用Ubuntu的服务器进行环境搭建的&#xff0c;在使用VS…...

1817_ChibiOS的RT线程

全部学习汇总&#xff1a; GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 1. 关于线程&#xff0c;有几个概念需要弄清楚&#xff1a;声明、生命循环、延迟、线程引用、线程队列、线程时间、优先级管理、调度。 2. 两个声明…...

牛客网刷题-(7)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…...

多模态领域的先进模型

多模态学习领域涌现了许多先进的模型&#xff0c;这些模型能够处理来自不同感官模态的信息并实现多模态任务。以下是一些先进的多模态学习模型&#xff1a; CLIP (Contrastive Language-Image Pretraining)&#xff1a;由OpenAI开发的CLIP是一种多模态预训练模型&#xff0c;能…...

列表自动向上滚动

列表自动向上滚动 鼠标放上去 自动停止滚动 <div id"list-detail-main"><div class"my_table_thead_tr"><div v-for"(item, index) in header" :key"index" class"my_table_thead_th">{{ item }}</div…...

嘴笨的技术人员怎么发言

对于嘴笨的人来说&#xff0c;即兴发言简直就是灾难&#xff0c;想想自己窘迫的模样&#xff0c;自己都受不了&#xff0c;但职场又避免不了这种场合&#xff0c;所以&#xff0c;就要靠一些技巧让我们顺利打开思路了。 那么&#xff0c;今天就分享几个解救过我的不同场景即兴发…...

vue源码分析(三)——new Vue 的过程(详解data定义值后如何获取的过程)

文章目录 零、准备工作1.创建vue2项目2.修改main.js 一、import Vue from vue引入的vue是哪里来的&#xff08;看导入node_modules包&#xff09;1&#xff1a; 通过node_modules包的package.json文件2&#xff1a; 通过配置中的main入口文件进入开发环境的源码&#xff08;1&a…...

软考系统架构师知识点集锦四:信息安全技术基础知识

一、考情分析 二、考点精讲 2.1信息加解密技术 2.1.1对称加密 概念:对称加密(又称为私人密钥加密/共享密钥加密) : 加密与解密使用同一密钥。特点:加密强度不高&#xff0c;但效率高;密钥分发困难。 (大量明文为了保证加密效率一般使用对称加密) 常见对称密钥加密算法:DES:…...

Vscode中不显示.ipynb文件单元格行号

找到设置&#xff0c;搜索line number&#xff1a; 看到下面那个Notebook: Line Numbers 控制单元格编辑器中行号的显示。&#xff0c;选择on即可&#xff1b;...

【Oracle】[INS-30131]执行安装程序验证所需的初始设置失败。

这里写目录标题 一、问题描述1 报错内容1.1 无法从节点“kotin”检索 exectask 的版本1.2 工作目录"xxx"无法在节点"kotin"上使用 2 相关环境2.1 安装软件2.2 安装系统 3 解决思路分析 二、解决方案1 方案一、 满足验证条件 - 不换系统1.1 第一步、检查文件…...

二进制部署kubernetes集群的推荐方式

软件版本&#xff1a; 软件版本containerdv1.6.5etcdv3.5.0kubernetesv1.24.0 一、系统环境 1.1 环境准备 角色IP服务k8s-master01192.168.10.10etcd、containerd、kube-apiserver、kube-scheduler、kube-controller-manager、kubele、kube-proxyk8s-node01后续etcd、conta…...

智能矩阵,引领商业新纪元!拓世方案:打破线上线下界限,开启无限营销可能!

在科技赋能商业大潮中&#xff0c;一切行业都在经历巨大变革&#xff0c;传统的营销策略被彻底改变&#xff0c;催生着无数企业去打造横跨线上线下、多维度、全方位的矩阵营销帝国。无数的成功案例已经告诉我们&#xff0c;营销不再只是宣传&#xff0c;而是建立品牌与消费者之…...

ADB原理(第四篇:聊聊adb shell ps与adb shell ps有无双引号的区别)

前言 对于经常使用adb的同学&#xff0c;不可避免的一定会这样用adb&#xff0c;比如我们想在手机里执行ps命令&#xff0c;于是在命令行中写下如下代码&#xff1a; adb shell ps -ef 或者 adb shell "ps -ef" 两种方式都可以使用&#xff0c;你喜欢用哪个呢&#…...

「网络编程」数据链路层协议_ 以太网协议学习

「前言」文章内容是数据链路层以太网协议的讲解。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、以太网协议简介二、以太网帧格式&#xff08;报头&#xff09;三、MTU对上层协议的影响四、ARP协议4.1 ARP协议的作用4.2 ARP协议报头 一、以太网协…...

通过python操作neo4j

在neo4j中创建结点和关系 创建结点 创建电影结点 例如&#xff1a;创建一个Movie结点&#xff0c;这个结点上带有三个属性{title:‘The Matrix’, released:1999, tagline:‘Welcome to the Real World’} CREATE (TheMatrix:Movie {title:The Matrix, released:1999, tagl…...

Ubuntu中查看电脑有多少个核——lscpu

1. 使用lscpu命令: 打开终端并输入以下命令: lscpu你会看到与CPU相关的详细信息。查找"CPU(s)"这一行来看总的核心数。另外&#xff0c;“Core(s) per socket”表示每个插槽或每个物理CPU的核数&#xff0c;“Socket(s)”表示物理CPU的数量。将这两个值相乘即得到总…...

Python学习笔记第七十二天(Matplotlib imread)

Python学习笔记第七十二天 Matplotlib imread读取图像数据修改图像裁剪图像图像颜色 后记 Matplotlib imread imread() 方法是 Matplotlib 库中的一个函数&#xff0c;用于从图像文件中读取图像数据。 imread() 方法返回一个 numpy.ndarray 对象&#xff0c;其形状是 (nrows,…...

安卓核心板_天玑700、天玑720、天玑900_5G模块规格参数

5G安卓核心板是采用新一代蜂窝移动通信技术的重要设备。它支持万物互联、生活云端化和智能交互的特性。5G技术使得各类智能硬件始终处于联网状态&#xff0c;而物联网则成为5G发展的主要动力。物联网通过传感器、无线网络和射频识别等技术&#xff0c;实现了物体之间的互联。而…...

CS224W2.2——传统基于特征的方法(边层级特征)

在这篇中&#xff0c;我们介绍了链接预测的重要任务&#xff0c;以及如何提取链接级特征来更好地解决这类问题。这在我们需要预测缺失的边或预测将来会出现的边的情况下很有用。我们将讨论的链路级功能包括基于距离的功能&#xff0c;以及本地和全局邻域重叠。 文章目录 1. 边层…...