并发——volatile 关键字

news2024/11/22 22:29:41

文章目录

  • 1. CPU 缓存模型
  • 2. 讲一下 JMM(Java 内存模型)
  • 3. 并发编程的三个重要特性
  • 4. 说说 synchronized 关键字和 volatile 关键字的区别

我们先要从 CPU 缓存模型 说起!

1. CPU 缓存模型

为什么要弄一个 CPU 高速缓存呢?

类比我们开发网站后台系统使用的缓存(比如 Redis)是为了解决程序处理速度和访问常规关系型数据库速度不对等的问题。 CPU 缓存则是为了解决 CPU 处理速度和内存处理速度不对等的问题。

我们甚至可以把 内存可以看作外存的高速缓存,程序运行的时候我们把外存的数据复制到内存,由于内存的处理速度远远高于外存,这样提高了处理速度。

总结:CPU Cache 缓存的是内存数据用于解决 CPU 处理速度和内存不匹配的问题,内存缓存的是硬盘数据用于解决硬盘访问速度过慢的问题。

为了更好地理解,我画了一个简单的 CPU Cache 示意图如下(实际上,现代的 CPU Cache 通常分为三层,分别叫 L1,L2,L3 Cache):

在这里插入图片描述

CPU Cache 的工作方式:

先复制一份数据到 CPU Cache 中,当 CPU 需要用到的时候就可以直接从 CPU Cache 中读取数据,当运算完成后,再将运算得到的数据写回 Main Memory 中。但是,这样存在 内存缓存不一致性的问题 !比如我执行一个 i++操作的话,如果两个线程同时执行的话,假设两个线程从 CPU Cache 中读取的 i=1,两个线程做了 1++运算完之后再写回 Main Memory 之后 i=2,而正确结果应该是 i=3。

CPU 为了解决内存缓存不一致性问题可以通过制定缓存一致协议或者其他手段来解决。

2. 讲一下 JMM(Java 内存模型)

在 JDK1.2 之前,Java 的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。而在当前的 Java 内存模型下,线程可以把变量保存本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致

在这里插入图片描述

要解决这个问题,就需要把变量声明为**volatile**,这就指示 JVM,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。

所以,volatile 关键字 除了防止 JVM 的指令重排 ,还有一个重要的作用就是保证变量的可见性。

在这里插入图片描述

3. 并发编程的三个重要特性

  1. 原子性 : 一个的操作或者多次操作,要么所有的操作全部都得到执行并且不会收到任何因素的干扰而中断,要么所有的操作都执行,要么都不执行。synchronized 可以保证代码片段的原子性。
  2. 可见性 :当一个变量对共享变量进行了修改,那么另外的线程都是立即可以看到修改后的最新值。volatile 关键字可以保证共享变量的可见性。
  3. 有序性 :代码在执行的过程中的先后顺序,Java 在编译器以及运行期间的优化,代码的执行顺序未必就是编写代码时候的顺序。volatile 关键字可以禁止指令进行重排序优化。

4. 说说 synchronized 关键字和 volatile 关键字的区别

synchronized 关键字和 volatile 关键字是两个互补的存在,而不是对立的存在!

  • volatile 关键字是线程同步的轻量级实现,所以**volatile 性能肯定比synchronized关键字要好**。但是**volatile 关键字只能用于变量而 synchronized 关键字可以修饰方法以及代码块**。
  • volatile 关键字能保证数据的可见性,但不能保证数据的原子性。synchronized 关键字两者都能保证。
  • volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized 关键字解决的是多个线程之间访问资源的同步性。

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

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

相关文章

分布式 - 服务器Nginx:一小时入门系列之静态网页配置

文章目录 1. 静态文件配置2. nginx listen 命令解析3. nginx server_name 命令解析4. nginx server 端口重复5. nginx location 命令 1. 静态文件配置 在 /home 文件下配置一个静态的AdminLTE后台管理系统: [rootnginx-dev conf.d]# cd /home [rootnginx-dev home…

flutter项目给安卓打正式包 和升级版本号

1.首先把flutter项目里的android目录整个拖进android studo里,运行一下看看是否能运行 2.Build->Generate Signed Bundle/APK… 点击APK->Next 如果没有key酒店及Create new…就生成新的key 点击Key store path:右边的图标选择保存路径 选择保存的路径,并且在Save…

【雕爷学编程】Arduino动手做(01)---干簧管传感器模块4

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…

logo一键生成的操作,没有设计经验也无妨

您可能会担心,没有设计经验如何设计一个独特而专业的标志(Logo)。但是,随着技术的进步,现在有许多一键生成操作的设计工具可供使用,使人们更容易创建自己的Logo。 什么是一键生成操作? 一键生成…

若依vue -【 100 ~ 更 】

100 主子表代码生成详解 1 新建数据库表结构(主子表) -- ---------------------------- -- 客户表 -- ---------------------------- drop table if exists sys_customer; create table sys_customer (customer_id bigint(20) not null…

《大型网站技术架构》第二篇 架构-高可用

高可用在公司中的重要性 对公司而言,可用性关系网站的生死存亡。对个人而言,可用性关系到自己的绩效升迁。 工程师对架构做了许多优化、对代码做了很多重构,对性能、扩展性、伸缩性做了很多改善,但别人未必能直观地感受到&#…

字节编码学习

字节编码学习 文章目录 字节编码学习01_字节与ASCII码表02_每个国家都有独特的码表03_国际化UTF-804_编码本和解码本不一致,乱码 01_字节与ASCII码表 public class Demo01 {public static void main(String[] args) {// 计算机的底层全部都是字节 ---- ----// 一个…

Android Studio实现简单ListView

效果图 MainActivity package com.example.listviewtest;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.widget.ListView;import com.example.listviewtest.adapter.PartAdapter; import com.example.listviewtest.bean.PartB…

多目标优化之MOEA-D算法,MATLAB代码,免费获取

今天给大家分享一期MOEA/D算法。1 引言 基于分解的多目标进化算法(MOEA/D)的核心思想将多目标优化问题被转化为一系列单目标优化子问题或者是多个多目标的子问题,然后利用子问题之间的邻域关系,采用协作的方式对这些子问题同时进行优化。从而向整个Paret…

大麦订单截图 一键生成订单截图

新版付款图样式展示 这个样式图就是在大麦刚付款完的一个订单截图,它的状态是等待卖家发货 下滑下载源码 下载源码:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3

LoRaWAN网关与网络服务器(NS)的通信LNS协议介绍

将 LoRaWAN网关连接到 LoRaWAN 网络服务器 (LNS) 是一个两步过程,该过程使用 WebSocket 作为传输协议来交换包含 JSON 编码对象的文本记录。 首先,网关向LNS查询LNS实际连接端点的URI。其次,它与该端点建立数据连接以接收设置信息。从那时起,LoRa 上行链路和下行链路帧通过…

golang专栏

GOLANG专栏订阅会员 Golang基础教程 Golang基础教程 Golang练手算法 Golang练手算法 Golang设计模式 Golang设计模式 Golang数据结构和算法 Golang数据结构和算法 Golang并发编程 Golang并发编程 ORM框架Gorm Golang ORM框架gorm Golang源码分析 Golang源码分析 MySQL教…

校园防欺凌防霸凌该怎么做

校园防欺凌防霸凌该怎么做 校园防欺凌和霸凌是一个长期而全面的过程,需要学生、教师和家长共同参与和努力。以下是一些可以采取的措施: 1. 教育和意识提高:通过教育和培训,提高学生、教师和家长对欺凌和霸凌的认识和了解。学校可…

机器人制作开源方案 | 超市服务机器人

作者:林江斌 岳沛霖 李锦扬 单位:北京理工大学 机械与车辆学院 指导老师:李忠新 朱杰 一、作品简介 1.设计背景 当前社会疫情防控已经成为常态化,超市是人员流动相对密集的公共场所,超市防疫也是社会防疫工作中重要…

linuxARM裸机学习笔记(4)----GPIO中断以及定时器中断实验

1.中断向量表 这个表里面存放的都是中断向量,中断服务程序的入口地址或存放中断服务程序的首地址成为中断向量。中断向量表是一系列中断服务程序入口地址组成的表,当某个中断触发的时候会自动跳转到中断向量表对应的中断服务程序的入口。 2.NVIC(内嵌向…

vue3+ts+element-plus大屏看板---横向轮播(anime.js)

vue3ts大屏看板---横向轮播(anime.js) 1. 安装和引入anime.js1. 安装2. 引入* 引入报错:引入时候报错 2. 基于vue3tsanime.js实现一个大屏组件轮播效果,如下1. 写一个需要轮播的模块样式✏️ 代码(有写注释&#xff09…

智能照明控制系统助力某商业综合体实现“双碳”-安科瑞黄安南

摘要:智能照明是当前非常普及的一种照明控制方式。广泛使用于建筑物,景观,公共场所。本文以智能照明在商业综合体中的应用为基础,主要介绍了智能照明系统的功能与特点,系统运用的效果,在建筑自动化系统中的地位及优势等…

oracle积累增量和差异增量

积累增量和差异增量: 对于 RMAN 来说,积累增量备份和差异增量备份都是增量备份的一种形式,它们之间的区别在于备份的范围和备份集的方式。 积累增量备份:在进行积累增量备份时,RMAN 会备份自最后一次完全备份或增量备…

JVM 性能优化思路

点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~ 一般在系统出现问题的时候,我们会考虑对 JVM 进行性能优化。优化思路就是根据问题的情况,结合工具进行问题排查,针对排查出来的可能问题…

06 - Stream如何提高遍历集合效率?

前面我们讲过 List 集合类,那我想你一定也知道集合的顶端接口 Collection。 在 Java8 中,Collection 新增了两个流方法,分别是 Stream() 和 parallelStream()。 1、什么是 Stream? 现在很多大数据量系统中都存在分表分库的情况…