volatile轻量级锁

news2024/11/28 7:34:03

一、背景

我们在写项目的时候,有时会使用多线程。为了保证一部分线程之间的通信,所以需要线程中的一些变量具有可见性。

说到线程可见性,对于Java而言,有两种方法实现:volatile和synchronized。

需要注意的是:volatile只用来保证该变量对所有线程的可见性,但不保证原子性。

虽然加锁同样能解决共享变量不可见性的问题,但是加锁和锁的释放过程都是会有性能消耗的,所以在解决共享变量不可见性的问题时,我们首选 volatile关键字

二、作用

volatile是Java提供的轻量级的同步机制,保证了可见性,不保证原子性。要了解volatile工作机制,首先要对Java内存模型(JMM)有初步的认识:

  • 每个线程创建时,JVM会为其创建一份私有的工作内存(栈空间),不同线程的工作内存之间不能直接互相访问。JMM规定所有的变量都存在主内存,主内存是共享内存区域,所有线程都可以访问
  • 线程对变量进行读写,会从主内存拷贝一份副本到自己的工作内存,操作完毕后刷新到主内存。所以,线程间的通信要通过主内存来实现。

 volatile的作用是:线程对副本变量进行修改后,其他线程能够立刻同步刷新最新的数值,这个就是可见性。同时还有禁止指令重排。

三、原理

volatile的内存语义

内存语义可以理解为 volatile 在执行计算时,内存中的要实现的功能与规则:

  • 一个 volatile 变量时,JMM 会把该线程对应的本地内存中的共享变量值刷新到主内存。
  • 一个 volatile 变量时,JMM 会把该线程对应的本地内存置为无效,并从主内存中读取共享变量。

 四、volatile 与 static

  • static 修饰的变量:多实例间,保证变量的唯一性。但是没有可见性和原子性的保证。
  • volatile 修饰的变量:多实例间,变量没有唯一性。但是能保证线程可见性,不保证原子性。

所以,static volatile 修饰的变量就是多实例间的唯一性,以及线程间的可见性。

五、总结

  • 适用场景:某个属性被多个线程共享,其中有一个线程修改了此属性,其他线程可以立即得到修改后的值,比如 booleanflag;或者作为触发器,实现轻量级同步。
  • volatile 变量的读写操作都是无锁的,低成本的。它不能替代 synchronized,因为它没有提供原子性和互斥性。
  • volatile 只能作用于属性,我们用volatile修饰属性,这样compilers就不会对这个属性做指令重排序。
  • volatile 可以在单例双重检查中(特殊场景)实现可见性和禁止指令重排序,从而保证安全性。

线程可见、禁止指令重排、不一定有原子性。

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

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

相关文章

Python中TensorFlow的长短期记忆神经网络(LSTM)、指数移动平均法预测股票市场和可视化...

原文链接:http://tecdat.cn/?p23689 本文探索Python中的长短期记忆(LSTM)网络,以及如何使用它们来进行股市预测(点击文末“阅读原文”获取完整代码数据)。 相关视频 在本文中,你将看到如何使用…

BART模型和 Electra模型对比

总结 Electra模型在使用较少的计算资源的情况下能够达到跟大语言模型相近的效果。但BART模型对于传统的BERT中加入了不同种制造noise的方式,是BERT和GPT的结合体。Electra模型主要是Generator模型和Discriminator模型的结合体。 未知参数设置,两个模型…

【Spring Boot】事务的隔离级别与事务的传播特性详解:如何在 Spring 中使用事务?不同隔离级别的区别?

文章目录 1 事务1.1 事务简介与 mysql 中的事务使用1.2 Spring 编程式事务(手动操作)1.3 Spring 声明式事务(自动操作)1.4 Transactional 的工作原理 2 事务的隔离级别2.1 事务的四大特性及事务的隔离级别回顾2.2 Spring 事务的隔…

【Unity2D】相机移动以及设置相机边界

添加相机 添加相机时,首先需要在unity中添加 Cinemachine 包 第一次使用这个包时,需要在Package Manager中搜索并安装 安装Camera Mechine包后,添加2D Camera 设置跟随对象为Ruby (从Hierarchy中将Ruby拖动到Follow中&#xff0…

非线性质量弹簧阻尼器的神经网络仿真研究(Matlab代码Simulink仿真实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码、Simulink仿真实现 💥1 概述 非线性质量弹簧阻尼器(Nonlinear Mass-Spring-Damper,NMSD)是一种常见的振动控制装置&#…

VS2017找不到QT头文件

一、我的电脑右键属性 - 》“高级系统设置” -》“环境变量” 增加环境变量Qt_INCLUDEPATH_ 值为QT的头文件目录 二、重启VS 发现波纹线不见了,证明设置环境变量后VS能识别到QT头文件了 原理是:vs导入qt项目附加包含目录继承值有Qt_INCLUDEPATH_

【视频的动态对比】

写在前面:本博客仅作记录学习之用,部分图片来自网络,如需引用请注明出处,同时如有侵犯您的权益,请联系删除! 文章目录 前言图像修复人脸与关键点检测修复图像修复视频 动态对比添加声音获取原视频音频融合声…

elementui全局给select option添加title属性

场景 有天边上的同事问了我一个问题,示例如下,有个数据特别长,导致下拉部分被横向撑大。希望在全局对所有的option进行处理,按照select的宽度,超出隐藏。 处理 方式一 第一眼看过去直接修改源码好了,修…

Mybatis基础模块-日志管理

文章目录 1. 适配器模式2. Log2.1 默认实现StdOutImpl2.2 Log4jImpl 3. LogFactory4. 解析配置和应用4.1 settings配置4.2 解析 5. jdbc日志5. 1 类图5.2 BaseJdbcLogger5.3 ConnectionLogger5.4 ConnectionLogger的具体应用 1. 适配器模式 适配器使接口不兼容的对象可以相互合…

用QFramework来重构 祖玛游戏

资料 Unity - 祖玛游戏 GitHub 说明 用QF一个场景就够了,在UIRoot下切换预制体达到面板切换。 但测试中当然要有一个直接跳到测试面板的 测试脚本,保留测试Scene(不然初学者也不知道怎么恢复测试Scene),所以全文按S…

SpringBoot整合Spring Security实现权限控制

文章目录 Spring Security介绍Spring Security案例1、快速搭建一个springboot工程2、导入SpringSecurity整合springboot工程3、认证3.1、登录流程校验3.2、入门案例的原理3.3、实现思路3.4、实现认证流程(自定义)3.5、正式实现3.5.1 实现数据库的校验3.5…

Linux 内核 ASoC 基本数据结构

Linux 内核 ASoC 框架建立了新的抽象,并通过一些中间层,将这些抽象接入 ALSA 音频框架。 Linux 内核 ASoC 设备驱动的结构如下图: Linux 内核 ASoC 设备驱动程序在 Linux 内核中扮演多个角色。 Linux 内核 ASoC 设备驱动程序在初始化阶段向…

MATLAB遗传算法求解带容量约束的物流配送选址问题实例

MATLAB遗传算法求解带容量约束的物流配送选址问题实例 作者:麦哥爱西芹 MATLAB遗传算法求解带容量约束物流配送中心选址问题代码实例 遗传算法编程问题实例: 在经度范围为(116, 118),纬度范围为(38, 40)的矩形区域内,散布着37个需…

第116天:免杀对抗-EDRSyscall-hookDLL反射注入白加黑隐写分离加载器

知识点 #知识点: 1、DLL劫持-自写&导入 2、DLL劫持-重写&分离 3、syscall-底层&项目#章节点: 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳花指令-资源 …

常微分方程建模R包ecode(一)——构建常微分方程系统

常微分方程在诸多研究领域中有着广泛应用,本文希望向大家介绍笔者于近期开发的R包ecode,该包采用简洁易懂的语法帮助大家在R环境中构建常微分方程,并便利地调用R图形接口,研究常微分方程系统的相速矢量场、平衡点、稳定点等解析性…

基于linux下的高并发服务器开发(第二章)- 2.20 kill、raise、abort函数

03 / 信号的5种默认处理动作 当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”&#…

X86设备启动过程

文章目录 一、电源自检二、BIOS自检三、引导设备选择四、主引导记录4.1 0x7c0 五、加载操作系统 x86计算机启动过程,主要分为这几个阶段:电源自检、BIOS自检、引导设备的选择、主引导记录、加载操作系统。 一、电源自检 当我们按下开关键后,…

消息队列总结(3)- RabbitMQ Kafka RocketMQ高可用方案

目录 1. 什么是高可用? 1.1 常见的高可用方法 1.2 消息队列的高可用 2. RabbitMQ的高可用方案 2.1 镜像队列 2.2 消息生产的确认机制 2.3 消息的持久化 3. Kafka的高可用方案 3.1 消息备份 3.2 ISR & IEO & HW 3.3 消息生产的确认机制 4. Rocke…

在虚拟机中安装anaconda和pytorch

首先我用的是VMware&#xff0c;ubuntu16.04. 首先建议安装anaconda,登录官网Free Download | Anaconda 下载完成后&#xff0c;来到安装文件目录处&#xff0c;打开终端&#xff0c; 然后在终端输入bash <anaconda文件名> 然后就一直enter和yes到底&#xff0c;直到安…

【后端面经】微服务构架 (1-3) | 熔断:熔断-恢复-熔断-恢复,抖来抖去怎么办?

文章目录 一、前置知识1、什么是熔断?2、什么是限流?3、什么是降级?4、怎么判断微服务出现了问题?A、指标有哪些?B、阈值如何选择?C、超过阈值之后,要不要持续一段时间才触发熔断?5、服务恢复正常二、面试环节1、面试准备2、面试基本思路三、总结 在微服务构架中…