synchronized、volatile关键字

Java中的synchronized关键字

synchronized关键字介绍

synchronized块是Java提供的一种原子性内置锁,Java中的每个对象都可以把它当作一个同步锁来使用,这些Java内置的使用者看不到的锁被称为内部锁,也叫作监视器锁。

线程的执行代码在进入synchronized代码块前会自动获取内部锁,这时候其他线程访问该同步代码块时会被阻塞挂起。

拿到内部锁的线程会在正常退出同步代码块或者抛出异常后或者在同步块内调用了该内置锁资源的wait系列方法时释放该内置锁。

内置锁是排它锁,也就是当一个线程获取这个锁后,其他线程必须等待该线程释放锁后才能获取该锁。

另外,由于Java中的线程是与操作系统的原生线程一一对应的,所以当阻塞一个线程时,需要从用户态切换到内核态执行阻塞操作,这是很耗时的操作,而synchronized的使用就会导致上下文切换。

synchronized的内存语义

前面介绍了共享变量内存可见性问题主要是由于线程的工作内存导致的,下面我们来讲解synchronized的一个内存语义,这个内存语义就可以解决共享变量内存可见性问题。

进入synchronized块的内存语义是把在synchronized块内使用到的变量从线程的工作内存中清除,这样在synchronized块内使用到该变量时就不会从线程的工作内存中获取,而是直接从主内存中获取。

退出synchronized块的内存语义是把在synchronized块内对共享变量的修改刷新到主内存。

其实这也是加锁和释放锁的语义,当获取锁后会清空锁块内本地内存中将会被用到的共享变量,在使用这些共享变量时从主内存进行加载,在释放锁时将本地内存中修改的共享变量刷新到主内存。

除可以解决共享变量内存可见性问题外,synchronized经常被用来实现原子性操作。另外请注意,synchronized关键字会引起线程上下文切换并带来线程调度开销。

Java中的volatile关键字

上面介绍了使用锁的方式可以解决共享变量内存可见性问题,但是使用锁太笨重,因为它会带来线程上下文的切换开销。

对于解决内存可见性问题,Java还提供了一种弱形式的同步,也就是使用volatile关键字。

该关键字可以确保对一个变量的更新对其他线程马上可见。

当一个变量被声明为volatile时,线程在写入变量时不会把值缓存在寄存器或者其他地方,而是会把值刷新回主内存。

当其他线程读取该共享变量时,会从主内存重新获取最新值,而不是使用当前线程的工作内存中的值。

volatile的内存语义和synchronized有相似之处,具体来说就是,当线程写入了volatile变量值时就等价于线程退出synchronized同步块(把写入工作内存的变量值同步到主内存),读取volatile变量值时就相当于进入同步块(先清空本地内存变量值,再从主内存获取最新值)。

下面看一个使用volatile关键字解决内存可见性问题的例子。

在这里插入图片描述
在这里插入图片描述
在这里使用synchronized和使用volatile是等价的,都解决了共享变量value的内存可见性问题,但是前者是独占锁,同时只能有一个线程调用get()方法,其他调用线程会被阻塞,同时会存在线程上下文切换和线程重新调度的开销,这也是使用锁方式不好的地方。而后者是非阻塞算法,不会造成线程上下文切换的开销。

但并非在所有情况下使用它们都是等价的,volatile虽然提供了可见性保证,但并不保证操作的原子性。
那么一般在什么时候才使用volatile关键字呢?

  • 写入变量值不依赖变量的当前值时。因为如果依赖当前值,将是获取一计算一写入三步操作,这三步操作不是原子性的,而volatile不保证原子性。
  • 读写变量值时没有加锁。因为加锁本身已经保证了内存可见性,这时候不需要把变量声明为volatile的。

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

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

相关文章

LLM Agent之RAG的反思:放弃了压缩还是智能么?

已经唠了三章的RAG,是时候回头反思一下,当前的RAG是解决幻觉的终点么?我给不出直接的答案,不过感觉当前把RAG当作传统搜索框架在大模型时代下的改良,这个思路的天花板高度有限~ 反思来源于对RAG下模型回答的直观感受&…

【软考中级-软件设计师】day3:程序设计语言基础知识

概述 练习题 程序设计语言的基本成分 练习题 编译程序基本原理 名词解释 词法分析 词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。进行词法分析的程序或者函数叫作…

Duboo-入门到学废【下篇】

目录 🥓1.dubbo-admin 🌭2.序列化 🧂3.超时 🥚4.重试 ❤️5.多版本 🧇6.负载均衡 🍟7.集群容错 1.dubbo-admin 💕💕💕 1.1dubbo-admin是什么 1.duboo-admin是一…

【大数据】Flink CDC 的概览和使用

Flink CDC 的概览和使用 1.什么是 CDC2.什么是 Flink CDC3.Flink CDC 前生今世3.1 Flink CDC 1.x3.2 Flink CDC 2.x3.3 Flink CDC 3.x 4.Flink CDC 使用5.Debezium 标准 CDC Event 格式详解 1.什么是 CDC CDC(Change Data Capture,数据变更抓取&#xf…

SpringCloud-高级篇(十三)

前面的主从集群可以应对Redis高并发读的问题,Redis主从之间可以做同步,为了提高主从同步时的性能,单节点Redis的内存不要设置太高,如果内存占用过多,做RDB的持久化,或者做全量同步的时候,导致大…

Kubernetes复习总结(二):Kubernetes容器网络

2、Kubernetes容器网络 1)、Docker网络原理 Docker默认使用的网络模型是bridge,这里只讲bridge网络模型 1)容器之间通信原理 当安装完docker之后,docker会在宿主机上创建一个名叫docker0的网桥,默认IP是172.17.0.1…

家具电子图册制作方法

​随着互联网的普及,越来越多的人选择在线购物,家具行业也不例外。为了满足消费者对高品质家具的需求,家具电子图册应运而生。与传统纸质图册相比,家具电子图册具有更高的转化率、更低的成本和更快的更新速度。 一、与纸质版相比有…

Linux 目录结构及其说明

Linux 操作系统遵循一种标准的目录结构,称为 Filesystem Hierarchy Standard(文件系统层次结构标准),其定义了不同目录的用途和内容。 浅蓝色文字 /(根目录): /根目录是整个文件系统的起点&…

迁移学习|代码实现

还记得我们之前实现的猫狗分类器吗?在哪里,我们设计了一个网络,这个网络接受一张图片,最后输出这张图片属于猫还是狗。实现分类器的过程比较复杂,准备的数据也比较少。所以我们是否可以使用一种方法,在数据…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)添加 删除 修改 释放

在上篇文章(处理任务队列中的任务)中我们讲解了处理任务队列中的任务的具体流程,eventLoopProcessTask函数的作用: 处理队列中的任务,需要遍历链表并根据type进行对应处理,也就是处理dispatcher中的任务。 // 处理任…

Linux之Ubuntu环境Jenkins部署前端项目

今天分享Ubuntu环境Jenkins部署前端vue项目 一、插件安装 1、前端项目依赖nodejs,需要安装相关插件 点击插件管理,输入node模糊查询 选择NodeJS安装 安装成功 2、配置nodejs 点击后进入 点击新增 NodeJS 配置脚手架类型:如果不填 默认npm …

华为HarmonyOS 创建第一个鸿蒙应用 运行Hello World

使用DevEco Studio创建第一个项目 Hello World 1.创建项目 创建第一个项目,命名为HelloWorld,点击Finish 选择Empty Ability模板,点击Next Hello World 项目已经成功创建,接来下看看效果 2.预览 Hello World 点击右侧的预…

[VUE]2-vue的基本使用

目录 vue基本使用方式 1、vue 组件 2、文本插值 3、属性绑定 4、事件绑定 5、双向绑定 6、条件渲染 7、axios 8、⭐跨域问题 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅…

RPC基础知识总结

RPC 是什么? RPC(Remote Procedure Call) 即远程过程调用,通过名字我们就能看出 RPC 关注的是远程调用而非本地调用。 为什么要 RPC ? 因为,两个不同的服务器上的服务提供的方法不在一个内存空间,所以&am…

【UML】第17篇 包图

目录 一、什么是包图 二、包图的作用: 三、应用场景: 四、绘图符号的说明: 五、语法: 六、其他要说的 一、什么是包图 包图(Package Diagram)是一种用于描述系统中包和包之间关系的UML图。包是一种将…

Thonny开发ESP32点灯

简介 ESP32是一款功能强大的低功耗微控制器,由乐鑫(Espressif)公司开发。它集成了Wi-Fi和蓝牙功能,适用于各种物联网应用。Thonny是一款基于Python的开源集成开发环境(IDE),专为MicroPython设计…

【数据分享】2024年我国主要城市地铁站点和线路数据

地铁站点与线路数据是我们经常会用到的一种基础数据。去哪里获取该数据呢? 今天我们就给大家分享一份2024年1月采集的全国有地铁城市的地铁站点与线路数据,数据格式为shp,数据坐标为wgs1984地理坐标。数据中不仅包括地铁,也包括轻…

Java Swing手搓坦克大战遇到的问题和思考

1.游戏中的坐标系颇为复杂 像素坐标系还有行列坐标,都要使用,这之间的互相转化使用也要注意 2.游戏中坦克拐弯的处理,非常重要 由于坦克中心点是要严格对齐到一条网格线,并沿着这条线前进的,如果拐弯不做处理&#…

法线变换矩阵的推导

背景 在冯氏光照模型中,其中的漫反射项需要我们对法向量和光线做点乘计算。 从顶点着色器中读入的法向量数据处于模型空间,我们需要将法向量转换到世界空间,然后在世界空间中让法向量和光线做运算。这里便有一个问题,如何将法线…

AI爆文变现:怼量也有技巧!如何提升你的创作收益

做AI爆文项目,赚小钱是没有问题的。 想要赚大钱,就是要做矩阵,怼量。 之前参加训练营的时候,也是要求怼量。 怼量,加高质量文章,让你的收益更高。 如何提升文章质量,减少AI味,AI…