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

news2024/12/23 4:31:18

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内存语义实现原理

        

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

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

相关文章

C语言系统化精讲(六):C语言选择结构和循环结构

文章目录 一、C语言选择结构1.1 if语句1.2 if…else语句1.3 else if语句1.4 if语句的嵌套1.5 条件运算符1.6 switch语句的基本形式1.7 多路开关模式的switch语句1.8 if…else语句和switch语句的区别 二、C语言循环结构2.1 C语言while循环和do while循环详解2.1.1 while循环2.1.…

基于机器视觉的停车位识别检测 计算机竞赛

简介 你是不是经常在停车场周围转来转去寻找停车位。如果你的车辆能准确地告诉你最近的停车位在哪里&#xff0c;那是不是很爽&#xff1f;事实证明&#xff0c;基于深度学习和OpenCV解决这个问题相对容易&#xff0c;只需获取停车场的实时视频即可。 该项目较为新颖&#xf…

为什么后端老是觉得前端简单?

首先&#xff0c;相对于后端来说&#xff0c;前端入门的门槛较低&#xff0c;有些人因程序员的高薪酬而转行&#xff0c;却又不愿学习更多的知识和技术&#xff0c;入行很久却还在做着最基础的工作&#xff0c;久而久之&#xff0c;前端工程师的技术水平参差不齐&#xff0c;进…

【嵌入式开发 Linux 常用命令系列 8 --代码格式修改工具 astyle】

文章目录 AStyle 介绍Ubuntu 下安装Windows 下安装 AStyle 介绍 AStyle&#xff0c;全名 Artistic Style&#xff0c;是一款源代码格式化工具。它可以自动格式化 C&#xff0c;C&#xff0c;C#&#xff0c;和Java源代码。使用它您可以轻松地对代码进行格式化&#xff0c;以满足…

python DevOps

1、用python的 subprocess就能写出ping 255个ip哪个不通。多进程就能快很多&#xff0c;用fork 2、子进程在循环中不写exit(),会发生再生成子进程&#xff0c;核心就是子进程下次循环就少一次&#xff0c;生出孙进程&#xff0c;循环少两次。。。直到结束 windows是没有os.fo…

Mac怎么清理磁盘空间?释放Mac磁盘空间有效方法

相信很多使用macOS系统的小伙伴都收到过提示“磁盘空间已满”消息&#xff0c;尤其是采用SSD固态硬盘的MacBook系列&#xff0c;120G的硬盘空间本就捉襟见肘&#xff0c;使用一段时间后&#xff0c;即使自己没有存放很多大文件&#xff0c; Mac的磁盘很快就满了。那么&#xff…

echarts的柱状图的重叠和堆叠实现两个柱体的显示和之前的差值显示

效果图 主要思路 准备三个柱体&#xff08;原计划&#xff0c;实际进度&#xff0c;差值&#xff09; 原计划和实际进度设置成重叠 {barWidth: 20,// yAxisIndex: 1,z: 1,name: 原计划,type: bar,stack: ab,emphasis: { // 点击柱体其他柱体颜色会变浅disabled: true},label…

山西电力市场日前价格预测【2023-10-27】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-10-27&#xff09;山西电力市场全天平均日前电价为347.06元/MWh。其中&#xff0c;最高日前电价为618.09元/MWh&#xff0c;预计出现在18: 15。最低日前电价为163.49元/MWh&#xff0c;预计…

VM虚拟机的安装与配置及操作系统的安装

目录 一.操作系统 1.简介 2.常见操作系统 2.1 windows操作系统 2.2 UNIX操作系统 2.3 linux操作系统 2.4 mac操作系统 2.5 嵌入式操作系统 3.个人版本和服务器版本的区别 4.Linux的版本介绍 4.1 Debian 4.2 Ubuntu 4.3 Redhat 4.4 Fedora 4.5 centos 二.VM虚拟…

微前端系列-样式隔离、元素隔离

样式隔离问题 各个应用之间可能相互设置标签样式&#xff0c;会相互影响&#xff0c;或者影响全局样式&#xff0c;比如应用A给body设置样式&#xff0c;应用B也给body设置样式 方法一 样式增加不同前缀 每个应用通过前缀独立区分开&#xff0c;京东micro-app默认是采用的这…

pika皮卡丘RCE靶场

pika |拼接命令&#xff0c;直接 find 寻找根目录下的文件&#xff0c;使用 grep 过滤 127.0.0.1 | find / | grep flag

超声电机工作原理

超声波电机的工作原理 在压电陶瓷振子上加高频交流电压时&#xff0c;利用逆压电效应或电致伸缩效应使定子产生微观机械振动。并将这种振动通过共振放大和摩擦耦合变换成旋转或直线型运动。 超声波驱动有两个前提条件&#xff1a; 需在定子表面激励出稳态的质点椭圆运动轨迹…

NTP(Network Time Protocol 网络时间协议)

作用 大数据产生与处理系统是各种计算设备集群的&#xff0c;计算设备将统一、同步的标准时间用于记录各种事件发生时序&#xff0c;如 E-MAIL 信息、文件创建和访问时间、数据库处理时间等。大数据系统内不同计算设备之间控制、计算、处理、应用等数据或操作都具有时序性&…

荣耀推送服务消息分类标准

前言 为了提升终端用户的推送体验、营造良好可持续的通知生态&#xff0c;荣耀推送服务将对推送消息进行分类管理。 消息分类 定义 荣耀推送服务将根据应用类型、消息内容和消息发送场景&#xff0c;将推送消息分成服务通讯和资讯营销两大类别。 服务通讯类&#xff0c;包…

如何在宝塔面板安装配置MySQL数据库并实现公网访问

宝塔安装MySQL数据库&#xff0c;并内网穿透实现公网远程访问 文章目录 宝塔安装MySQL数据库&#xff0c;并内网穿透实现公网远程访问前言1.Mysql服务安装2.创建数据库3.安装cpolar3.2 创建HTTP隧道 4.远程连接5.固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网…

【科普】干货!带你从0了解移动机器人(六) (底盘结构类型)

牵引式移动机器人&#xff08;AGV/AMR&#xff09;&#xff0c;通常由一个牵引车和一个或多个被牵引的车辆组成。牵引车是机器人的核心部分&#xff0c;它具有自主导航和定位功能&#xff0c;可以根据预先设定的路径或地标进行导航&#xff0c;并通过传感器和视觉系统感知周围环…

音视频开发(一)ffmpeg 简单学习

前言 简单音视频处理。 学习自&#xff1a; 小破站FFmpeg最强教学丨入门FFmpeg看这一篇就够了丨从入门到放弃系列_哔哩哔哩_bilibili 01 下载、配置_哔哩哔哩_bilibili 基础知识 音视频处理基本都是&#xff1a;采样-处理得到帧队列-编码得到包队列-封装得到文件。 视频…

怎么设置禁止使用U盘

怎么设置禁止使用U盘 在工作中&#xff0c;数据对企业来说是尤为重要的&#xff0c;一旦企业或机构的数据泄露&#xff0c;就会给企业或机构带来极大的损失&#xff0c;企业为了保护公司数据的安全&#xff0c;往往禁用公司电脑使用U盘&#xff0c;禁用U盘也成为了企业的必要措…

Allegro电商平台:为卖家打开全球市场,为消费者带来无限选择

Allegro电商平台是一个全球性的在线零售平台&#xff0c;为卖家提供了一个广阔的市场&#xff0c;让他们可以在全球范围内销售产品。这个平台以其丰富的产品类别、便捷的购物体验和优质的客户服务而受到卖家和消费者的欢迎。本文将介绍Allegro电商平台的特点&#xff0c;以及卖…

【@胡锡进】大模型量化分析- 潍柴动力 000338.SZ

对于预测股票价格的问题&#xff0c;有许多不同的方法可以尝试。下面我将为你分别使用SARIMA、简单移动平均线、指数加权移动平均线、Bollinger带、相对强弱指标、随机指标、线性回归、随机森林回归、支持向量回归法、自回归移动平均法和长短期记忆模型来预测潍柴动力未来3天的…