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

关于对Java中volatile关键字的理解与简述

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://blog.csdn.net/m0_69908381/article/details/134430096
出自【进步*于辰的博客】

启发之作:Java volatile关键字最全总结:原理剖析与实例讲解(简单易懂)(转发)。
参考笔记二,P73、P74.1。

文章目录

  • 1、关于JMM规范
  • 2、关于`volatile`
  • 3、关于`volatile`的运用
  • 4、最后

在学习 volatile关键字之前,我们先了解一下JMM规范和并发编程中的三个概念。

1、关于JMM规范

什么是 J M M ? \color{grey}{什么是JMM?} 什么是JMM
JMM(Java module memory,Java内存模型)是一个抽象概念,并不真实存在于内存。它是用于定义程序中各个变量(成员变量、类变量、数组元素等)的一组规范和规则,指定变量的访问方式。

规定: \color{red}{规定:} 规定:

  1. 线程解锁之前必须将共享变量刷新回主内存;
  2. 线程加锁之前必须读取主内存中变量的最新值到工作空间;
  3. 解锁和加锁必须是同一把锁。

大家可能不解其意,这就需要涉及另一个概念: 线程空间 \color{green}{线程空间} 线程空间.。
什么是线程空间? \color{grey}{什么是线程空间?} 什么是线程空间?
程序执行JMM规范的实体是线程,当线程创建时,JMM会为其创建一个私有内存(也称为 工作内存、本地内存或栈空间 工作内存、本地内存或栈空间 工作内存、本地内存或栈空间)。JMM规定所有变量都保存在主内存,线程访问变量时需为变量创建一个副本至工作内存进行操作,完成后将变量值返回主内存,且线程通信在主内存进行。

2、关于volatile

并发编程的三个概念:

  1. 可见性: \color{green}{可见性:} 可见性:指线程对变量的修改,其他线程可见;
  2. 原子性: \color{blue}{原子性:} 原子性:指线程对变量的操作的整个过程不会被阻塞或分割;
  3. 有序性: \color{brown}{有序性:} 有序性:也称为 “指令重排” \color{red}{“指令重排”} 指令重排,指程序运行时,编译器基于提高性能需要,以指令间的数据依赖性作为依据对指令进行重新排列。执行顺序:编译器重排 → 指令并行重排 → 内存系统重排。

volatile 是什么? \color{grey}{是什么?} 是什么?
volatile是一种轻量级的同步机制,而synchronized是一种重量级的同步机制(“级”是指对变量访问的限制程度)。volatile遵循JMM规范实现了可见性和有序性,但不保证原子性。因此,限制线程在访问由volatile修饰的变量时,从主内存获取数据,而不是从工作内存,在数据操作完成后再刷新回主内存,故在保证原子性的情况下,可实现线程安全。

注:如何保证原子性?如程序中不存在多线程对变量进行非原子性操作,举个例:a++是原子操作,而a+=1不是。

volatile 的一个经典应用: \color{red}{的一个经典应用:} 的一个经典应用:

关于单例模式,可查阅博文【关于对【单例模式_java】的理解与简述】。

从文中可知, “双重检测机制” \color{green}{“双重检测机制”} 双重检测机制可解决“懒汉式”的线程安全问题。其实,“双重同步锁”也有漏洞。
以那篇博文的示例为例:

instance = new Singleton();

实例化分为三步:1、创建实例,分配内存;2、实例初始化;3、令instance指向此实例。其中,2和3都依赖于1,而2与3之间没有依赖关系,故指令重排会将2与3对调(原因可能是实例初始化耗时较长)。因此,当instance指向实例时,实例可能还未初始化,下一个线程就会出现并发问题(暂不清楚原因),用volatile禁止指令重排即可解决。

3、关于volatile的运用

学以致用才是检验学习效果最好的方法。从上文可知,volatile关键字可以解决这两种情形下的线程安全问题。

  1. 多线程并发访问变量,线程体中不存在非原子操作的情况;
  2. 弥补 双重同步锁 \color{green}{双重同步锁} 双重同步锁的漏洞。

那我们就一一测试检测一下。

1、情形一:创建10个线程对同一个成员变量并发修改1万次。
示例。

volatile int a;
public static void main(String[] args) throws Exception {C c1 = new C();// C 是当前类名int i = 10;while (i-- > 0) {new Thread(() -> {int n = 10000;while (n-- > 0) {c1.a++;}}).start();}Thread.sleep(10000);// 主线程停留10s足以保证10个子线程运行完成System.out.println(c1.a);
}

最后c1.a的输出结果并不是100000(10s足够10个子线程执行完成)。可见,并未解决线程安全问题。

2、情形二:多线程并发调用newInstance()获取单例模式类实例。
实体类。

class SingleTon {private static SingleTon instance;private SingleTon() {}public static SingleTon newInstance() {if (instance == null) {synchronized (SingleTon.class) {if (instance == null) {instance = new SingleTon();}}}return instance;}
}

测试:创建一万个线程并发调用newInstance(),判断获取的实例是否都为单例。

List<SingleTon> list = new Vector<>();
int i = 10000;
while (i-- > 0) {new Thread(() -> {SingleTon s1 = SingleTon.getInstance();if (list.size() > 0 && list.indexOf(s1) == -1)System.out.println("违反单例");// 未执行list.add(s1);}).start();
}
Thread.sleep(1000);
System.out.println(list.size());// 10000

Vector 类线程同步,故list.add(s1)也是线程同步的。
未打印“违反单例”,表示list中存储的所有s1都指向同一个实例,保证了“单例”,说明线程安全。

不过,还证明不了这是volatile的功劳,因为 双重检测机制 \color{blue}{双重检测机制} 双重检测机制本身对线程安全就有很大的保证性。
于是,我把10000改成了100000,好吧。。。还是未打印“违反单例”,看来双重同步锁真的很强大。

4、最后

大家肯定也看出来了,在上面的示例中,我的本意是想创建十万个线程调用newInstance(),通过是否打印“违反单例”来触发 双重同步锁 \color{brown}{双重同步锁} 双重同步锁的漏洞,然后用volatile声明instance来解决线程安全问题,可我失败了。。。
大家也看得出来,我对volatile关键字的理解还不够透彻,毕竟哪有这样测试的。
因此,本文的目的是为了让大家对volatile关键字有一个初步的了解,我继续努力!!

本文完结。

相关文章:

关于对Java中volatile关键字的理解与简述

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/134430096 出自【进步*于辰的博客】 启发之作&#xff1a;Java volatile关键字最全总结&#xf…...

37 _ 贪心算法:如何用贪心算法实现Huffman压缩编码?

基础的数据结构和算法我们基本上学完了,接下来几节,我会讲几种更加基本的算法。它们分别是贪心算法、分治算法、回溯算法、动态规划。更加确切地说,它们应该是算法思想,并不是具体的算法,常用来指导我们设计具体的算法和编码等。 贪心、分治、回溯、动态规划这4个算法思想…...

Unity中Shader矩阵的逆矩阵

文章目录 前言一、逆矩阵的表示二、逆矩阵的作用四、逆矩阵的计算五、顺序的重要性六、矩阵的逆总结1、求矩阵的逆前&#xff0c;这个矩阵必须得是个方阵2、只有 A x A ^-1^ A^-1^ x A 1时&#xff0c;A的逆才是A^-1^3、求2x2矩阵的逆&#xff1a;交换 a 和 b 的位置&#xf…...

我给网站做公安备案年度安全评估

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 差不多从2020年开始&#xff0c;我们的网站每年11月左右就要去公安备案做一次年度的安全评估&#xff0c;而现在又新增了APP和小程序备案。如下图所示&#xff1a; 评估的内容也很简单&#xff0c…...

iceoryx(冰羚)-通信中间件解析

iceoryx(冰羚)-简介 iceoryx(冰羚)-Architecture iceoryx(冰羚)-Service Discovery iceoryx(冰羚)-examples-callbacks iceoryx(冰羚)-Listener设计 [iceoryx(冰羚)-ipc消息通信] [iceoryx(冰羚)-共享内存实现]...

Windows系统CMake+VS编译protobuf

目录 一些名词CMake构建VS工程下载protobuf源码下载CMake编译QT中使用 方案二失败&#xff1a;CMakeQT自带的Mingw编译参考链接 一些名词 lib dll lib库实际上分为两种&#xff0c;一种是静态链接lib库或者叫做静态lib库&#xff0c;另一种叫做动态链接库dll库的lib导入库或称…...

HarmonyOS开发(三):ArkTS基础

1、ArkTS演进 Mozilla创建了JS ---> Microsoft创建了TS ----> Huawei进一步推出ArkTS 从最初的基础逻辑交互&#xff08;JS&#xff09;,到具备类型系统的高效工程开发&#xff08;TS&#xff09;,再到融合声明式UI、多维状态管理等丰富的应用开发能力&…...

Java排序算法之堆排序

图解 堆排序是一种常见的排序算法&#xff0c;它借助了堆这种数据结构。堆是一种完全二叉树&#xff0c;它可以分为两种类型&#xff1a;最大堆和最小堆。在最大堆中&#xff0c;每个结点的值都大于等于它的子结点的值&#xff0c;而在最小堆中&#xff0c;每个结点的值都小于等…...

『GitHub项目圈选02』一款可实现视频自动翻译配音为其他语言的开源项目

&#x1f525;&#x1f525;&#x1f525;本周GitHub项目圈选****: 主要包含视频翻译、正则填字游戏、敏感词检测、聊天机器人框架、AI 换脸、分布式数据集成平台等热点项目。 1、pyvideotrans pyvideotrans 是一个视频翻译工具&#xff0c;可将一种语言的视频翻译为另一种语…...

Unity - Cinemachine

动态获取Cinemachine的内部组件 vCam.GetCinemachineComponent<T>() 动态修改Cinemachine的Transposer属性 var vCamComp transfrom.GetComponent<CinemachineVirtualCamera>(); var transposerComp vCamComp.GetCinemachineComponent<CinemachineTransposer&…...

准备搞OpenStack了,先装一台最新的Ubuntu 23.10

正文共&#xff1a;1113 字 25 图&#xff0c;预估阅读时间&#xff1a;2 分钟 依稀记得前面发了一篇Ubuntu的安装文档&#xff08;66%的经验丰富开发者和69%的学生更喜欢的Ubuntu的安装初体验&#xff09;&#xff0c;当时安装的是20.04.3的版本&#xff0c;现在看来已经是非常…...

Android 12 客制化修改初探-Launcher/Settings/Bootanimation

Android 12 使用 Material You 打造的全新系统界面&#xff0c;富有表现力、活力和个性。使用重新设计的微件、AppSearch、游戏模式和新的编解码器扩展您的应用。支持隐私信息中心和大致位置等新的保护功能。使用富媒体内容插入功能、更简便的模糊处理功能、经过改进的原生调试…...

【JavaEE初阶】 HTML基础详解

文章目录 &#x1f38b;什么是HTML&#xff1f;&#x1f340;HTML 结构&#x1f6a9;认识标签&#x1f6a9;HTML 文件基本结构&#x1f6a9;快速生成代码框架 &#x1f384;HTML 常见标签&#x1f6a9;注释标签&#x1f6a9;标题标签: h1-h6&#x1f6a9;段落标签: p&#x1f6…...

C# Socket通信从入门到精通(10)——如何检测两台电脑之间的网络是否通畅

前言: 我们在完成了socket通信程序开发以后,并且IP地址也设置好以后,可以先通过一些手段来测试两台电脑之间的网络是否通畅,如果确认了网络通畅以后,我们再测试我们编写的Socket程序。 1、同时按下键盘的windows键+"R"键,如下图: 下面两张图是两种键盘的情…...

python科研绘图:P-P图与Q-Q图

目录 什么是P-P图与Q-Q图 分位数 百分位数 Q-Q图步骤与原理 Shapiro-Wilk检验 绘制Q-Q图 绘制P-P图 什么是P-P图与Q-Q图 P-P图和Q-Q图都是用于检验样本的概率分布是否服从某种理论分布。 P-P图的原理是检验实际累积概率分布与理论累积概率分布是否吻合。若吻合&#xf…...

浅尝:iOS的CoreGraphics和Flutter的Canvas

iOS的CoreGraphic 基本就是创建一个自定义的UIView&#xff0c;然后重写drawRect方法&#xff0c;在此方法里使用UIGraphicsGetCurrentContext()来绘制目标图形和样式 #import <UIKit/UIKit.h>interface MyGraphicView : UIView endimplementation MyGraphicView// Onl…...

网络安全黑客技术自学

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防…...

【文件读取/包含】任意文件读取漏洞 afr_3

1.1漏洞描述 漏洞名称任意文件读取漏洞 afr_3漏洞类型文件读取/包含漏洞等级⭐⭐⭐⭐⭐漏洞环境docker攻击方式 1.2漏洞等级 高危 1.3影响版本 暂无 1.4漏洞复现 1.4.1.基础环境 靶场docker工具BurpSuite 1.4.2.环境搭建 1.创建docker-compose.yml文件 version: 3.2 servi…...

第四章:单例模式与final

系列文章目录 文章目录 系列文章目录前言一、单例模式二、final 关键字总结 前言 单例模式与final关键字。 一、单例模式 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。就像是经典的棋谱&#xff0c;不同的棋局&#xff0c;我…...

深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解

深入学习 Android Framework 第三&#xff1a;深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解 文章目录 深入学习 Android Framework前言一、Android 系统的启动流程1. 流程图2. 启动流程概述 二、源码详解1. 时序图2. 源代码1、ZygoteInit # main…...

[AI/Agent/社交] AI Agent社交网络产品:MoltBook => InStreet

Julia&#xff08;julialang.org&#xff09;由Stefan Karpinski、Jeff Bezanson等在2009年创建&#xff0c;目标是融合Python的易用性、C的高性能、R的统计能力、Matlab的科学计算生态。 其核心设计哲学是&#xff1a; 高性能&#xff1a;编译型语言&#xff08;JIT&#xff0…...

当SPC焕发新生:云质信息重构制造质量管理新范式

传统SPC&#xff1a;那些让人头疼的“老毛病”说实话&#xff0c;很多企业斥巨资引入的SPC软件&#xff0c;实际使用体验与高级版Excel相差无几。数据需手动导入&#xff0c;图表需逐一点选生成&#xff0c;想要进行跨维度分析&#xff0c;更是要先将数据导出&#xff0c;借助其…...

PWM技术原理与工程实践全解析

1. PWM技术基础解析脉冲宽度调制&#xff08;PWM&#xff09;作为现代电子电力控制的核心技术&#xff0c;其本质是通过调节脉冲信号的导通时间比例来实现对功率的有效控制。我第一次接触这个概念是在调试直流电机调速项目时&#xff0c;当时被其精妙的设计思想所震撼。1.1 关键…...

程序员副业指南:从技术到收入的10种变现路径

CSDN程序员副业图谱技术文章大纲副业方向概览技术博客与内容创作&#xff1a;分享技术经验、教程、行业见解在线教育与课程开发&#xff1a;录制视频课程、开设直播讲座开源项目与工具开发&#xff1a;参与或主导开源项目&#xff0c;开发实用工具自由职业与远程工作&#xff1…...

三菱PLC与组态王四层电梯控制系统:详细图纸与IO分配解释

三菱PLC和组态王4层电梯四层电梯控制系统 我们主要的后发送的产品有&#xff0c;带解释的梯形图接线图原理图图纸&#xff0c;io分配&#xff0c;组态画面实验室四层电梯模型卡成狗的时候&#xff0c;真的恨自己当初梯形图只会写互锁单按钮那种幼儿园题。后来拆前辈的旧板子加…...

OpenClaw Exec Approvals 机制:在安全与效率之间寻找平衡

OpenClaw Exec Approvals 机制&#xff1a;在安全与效率之间寻找平衡当你第一次看到 /approve 弹窗时&#xff0c;是选择 allow-once 还是 allow-always&#xff1f;这个看似简单的决定&#xff0c;背后是安全与便利的永恒博弈。引言 在 Agent 开发和工作流自动化的世界里&…...

Phi-3-mini-4k-instruct新手入门:Ollama部署详解,从安装到第一个对话

Phi-3-mini-4k-instruct新手入门&#xff1a;Ollama部署详解&#xff0c;从安装到第一个对话 1. 认识Phi-3-mini-4k-instruct&#xff1a;轻量级AI助手 Phi-3-mini-4k-instruct是一个仅有38亿参数的轻量级语言模型&#xff0c;由微软团队开发。虽然体积小巧&#xff0c;但它在…...

余姚加工中心编程培训排行榜单

舜龙模具数控培训执行标准&#xff1a;学习进度一对一、培训一人、合格一人、成就一人&#xff1b;舜龙自有模具工厂&#xff0c;全程实战教学&#xff0c;所学贴合岗位实操&#xff0c;毕业即可对接就业。1998年-2026年&#xff0c;舜龙28年匠心传承。舜龙模具数控培训&#x…...

如何用GPU加速的MediaPipe TouchDesigner插件实现实时视觉交互

如何用GPU加速的MediaPipe TouchDesigner插件实现实时视觉交互 【免费下载链接】mediapipe-touchdesigner GPU Accelerated MediaPipe Plugin for TouchDesigner 项目地址: https://gitcode.com/gh_mirrors/me/mediapipe-touchdesigner MediaPipe TouchDesigner插件是一…...

玩转ESP32-S3调试:GDB高级命令与自定义调试技巧大全

玩转ESP32-S3调试&#xff1a;GDB高级命令与自定义调试技巧大全 调试嵌入式系统时&#xff0c;GDB的强大功能往往被低估。对于ESP32-S3开发者来说&#xff0c;掌握GDB的高级调试技巧可以显著提升解决复杂问题的效率。本文将深入探讨如何利用GDB的watch命令、自定义命令、跳转执…...