4. Java 的线程安全机制之`volatile`

前言:在多线程编程过程中,线程安全是一个非常重要的概念,它有助于保证多线程程序的正确性和健壮性。其中,volatile是实现线程安全的一种方式,保证内存的立马可见,下面将会详细介绍。


文章目录

  • 是什么
  • 为什么
  • 怎么办
  • 会怎样
  • 纸上得来终觉浅
  • 总结


🚀 作者简介:作为某云服务提供商的后端开发人员,我将在这里与大家简要分享一些实用的开发小技巧。在我的职业生涯中积累了丰富的经验,希望能通过这个博客与大家交流、学习和成长。技术栈:Java、PHP、Python、Vue、React


本文收录于三木的🎈 「Java探索者之路」系列专栏,这个专栏旨在引领Java开发者踏上一段真正探索Java世界的旅程。
我们将深入探讨Java编程的方方面面,从基础知识到高级技巧,从实践案例到最新趋势,帮助你成为一名卓越的Java探索者。如果有想进入Java后端领域工作的同学,这个专栏会对你有所帮助,欢迎关注起来呀

🔥「面试」这个专栏的灵感来自于许多粉丝私信,大家向我咨询有关面试的问题和建议。我深感荣幸和责任,希望通过这个专栏,能够为大家提供更多关于面试的知识、技巧和经验。我们将一起探讨面试。期待粉丝们ssp的offer喜讯。

🌼 本人也会持续的去关注AIGC以及人工智能领域的一些动向并总结到博客中,大家感兴趣的可以关注一下我的「AI」专栏
🌊 「Python爬虫」的入门学习系列,大家有兴趣的可以看一看


🌹一起学习,互三互访,顺评论区有访必回,有关必回!!!


是什么

volatile是Java中的一种关键字,用于标记变量,表示该变量是易变的。当一个变量被声明为volatile时,它的值将不会被缓存在寄存器、对其他线程不可见的缓存或者其他不可见的地方,而是被强制性地保存到主内存中。

为什么

多线程同时访问一个共享变量时,可能会出现数据不一致的问题。例如线程A修改了共享变量的值,但是线程B并没有立即看到这个修改,而是从缓存中读取了旧的值,导致程序出现错误。使用volatile关键字可以防止这种情况的发生,保证共享变量的可见性,从而实现线程安全。

怎么办

使用volatile关键字需要注意以下几点:

  • 1.将共享变量声明为volatile

     public volatile int sharedVar;
    
  • 2.不要使用volatile关键字修饰引用类型

    对于引用类型,其内部的字段可能会发生改变,但是这并不会触发volatile变量的可见性,因此建议使用锁或者其他线程安全的方式来保证引用类型的线程安全。

  • 3.不要对变量进行复合操作

    复合操作是指对变量进行两个或者更多的操作,例如i++、x+=5等,在多线程环境下这会导致出现不一致的情况。建议使用AtomicInteger等原子操作类来代替复合操作。

  • 4.不要过度依赖volatile关键字

    volatile关键字仅保证变量的可见性,不能保证变量的原子性和互斥性,因此需要配合其他线程安全的机制一起使用。

会怎样

使用volatile关键字能够保证共享变量的可见性,避免出现数据不一致的问题。但是volatile不能保证操作的原子性和互斥性,因此需要搭配其他线程安全的机制来保证程序的正确性。

纸上得来终觉浅

下面是一个使用volatile关键字的示例代码,演示了如何保证共享变量在多线程环境下的可见性。

public class VolatileExample {private volatile boolean flag = false;public void setFlag() {flag = true;}public void checkFlag() {while (!flag) {// do something}System.out.println("Flag is true");}public static void main(String[] args) {VolatileExample example = new VolatileExample();new Thread(example::checkFlag).start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}example.setFlag();}
}

在该示例代码中,定义了一个私有的volatile变量flag,并提供了两个方法setFlag和checkFlag。在setFlag方法中将flag设置为true,在checkFlag方法中不断循环等待flag变为true,一旦变为true,就打印出"Flag is true"的信息。

在main方法中启动一个线程调用checkFlag方法,同时让主线程休眠1秒钟后再调用setFlag方法将flag变为true。由于flag是volatile变量,当主线程将flag变为true时,另一个线程能够立即看到这个修改并结束等待,打印出"Flag is true"的信息。这样就保证了共享变量flag的可见性,避免了出现数据不一致的问题。

总结

本文详细介绍了volatile关键字在Java中的作用和使用方法,以及需要注意的几点事项。使用volatile关键字可以有效地实现线程安全,但是需要注意其局限性,不能过度依赖。在多线程编程过程中,需要根据具体情况来选择合适的线程安全机制,保证程序的正确性和健壮性。

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

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

相关文章

OpenCV(三十二):轮廓检测

1.轮廓概念介绍 在计算机视觉和图像处理领域中,轮廓是指在图像中表示对象边界的连续曲线。它是由一系列相邻的点构成的,这些点在边界上连接起来形成一个封闭的路径。 轮廓层级: 轮廓层级(Contour Hierarchy)是指在包含…

雅思 《九分达人》阅读练习(二)

目录 雅思阅读练习 《九分达人》test3 paragraph3 1.单词含义要记准确,敏感度要上来。 2.找准定位,之后理解句子大致含义。 说说关于判断题的做题方法 关于“承认”有哪些单词 同替词汇 think 可以用什么其他单词来替换 单词 一些疑问 I have…

win10 sourcetree打开一闪就退出

参考文档: 解决方案参考文档一: Solved: cant install Sourcetree on Windows 10Solved: when I double-click the installation file or run as administrator,I can see a splash screen and disappear in 10 seconds,then I open thehttps://community.atlassian.com/t5…

【C++】vector的模拟实现【完整版】

目录 一、vector的默认成员函数 1、vector类的大体结构 2、无参构造函数 3、拷贝构造函数 4、Swap(operator需要用) 5、赋值重载operator 6、析构函数 二、vector的三种遍历方式 1、size和capacity(大小和容量) 2、 operator[]遍历 3、迭代器iterator遍历和范围for 三…

multiple JSON fields named delFlag

错误原因 如果A是父类,A类有一个字段a,如果B类继承了A类,并且,B类也定义一个a 继承又涉及到覆盖和的问题,就是子类和父类可以同时有用一个方法或者变量,但是在类的继承使用过程没有问题,但是G…

LA@二次型分类@正定二次型@主子式

文章目录 abstract引言正定二次型小结可逆线性变换不改变二次型的正定性二次型是正定的充要条件推论:正定矩阵和特征值正定二次型(正定矩阵)性质 负定二次型负定二次型判定条件 k阶顺序主子式赫尔维茨定理:主子式判定二次型正定性和负定性 二次型分类小结有定二次型不定二次型 …

php常用算法

许多人都说 算法是程序的核心,一个程序的好于差,关键是这个程序算法的优劣。作为一个初级phper,虽然很少接触到算法方面的东西 。但是对于冒泡排序,插入排序,选择排序,快速排序四种基本算法,我想还是要掌握…

微信h5扫码接口范例:多个扫码框支持的办法,通过引入一个参数来区分及使用localStorage保证之前扫到的数据不丢失

测试方法: 多个扫码框支持的办法,通过引入一个参数来区分及使用localStorage保证之前扫到的数据不丢失 测试效果: 页面打开后尝试点击不同的扫码按钮去扫描看看,会发现扫的值不会错乱,都会显示到对应的输入框中。 &l…

Oracle数据库环境变量配置以及可能遇到的问题解决

一、如何配置Oracle数据库环境变量(以win10为例) 1、找到此电脑,鼠标右键,点击属性。 2、点击属性成功后,进入如下页面,找到“高级系统设置”,点击进入。 3、找到环境变量,点击进入…

Capstone 反汇编引擎

文章目录 前言一、Capstone简介二、示例代码 前言 介绍了capstone反汇编引擎的用法 一、Capstone简介 Capstone 是一个轻量级的多平台、多架构的反汇编框架,用纯 C 语言实现。可以说它是如今世界上最优秀的反汇编引擎,IDA,Radare2&#xf…

Unity Inspector面板上显示Api

serializeField】——将私有类型和保护类型可视化到面板上【System.serializeField】——将自定义类型可视化到面板上【HideIninspector】——将公共变量隐藏【Header(“分组说明”)】——将可视化变量进行分组【Tooltip(“内容说明”&#x…

STM32F4X RTC

STM32F4X RTC 什么是RTCSTM32F4X RTCSTM32F4X RTC框图STM32F4X RTC计数频率STM32F4X RTC日历STM32F4X RTC闹钟 STM32F4X RTC例程 什么是RTC RTC全程叫Real-Time Clock实时时钟,是MCU中一个用来计时的模块。RTC的一个主要作用是用来显示实时时间,就像日常…

pip安装skimage的方法

在安装skimage时,可能会报错误: 可以尝试:pip install scikit-image进行安装,使用时只需要:import skimage

介绍一些开发用到的工具

Sourcetree :Git 界面操作工具,真心好用 uTool:效率工具平台,可以了解一下,提供了很多强大的工具,加强了对电脑的操作 MobaXterm:带有 X11 服务器、选项卡式 SSH 客户端、网络工具等的增强型 Wi…

《消息队列》专栏介绍

《消息队列》专栏介绍 目录 《消息队列》专栏介绍专栏导言什么是消息队列呢?应用场景(作用) 为什么要用消息队列呢?异步处理削峰填谷 举个例子 分布式消息队列的优势 应用解耦优点发布订阅优点 分布式消息队列应用场景不同消息队列…

武警三维数字沙盘电子沙盘虚拟现实模拟推演大数据人工智能开发教程第15课

部队三维数字沙盘电子沙盘虚拟现实模拟推演大数据人工智能开发教程第15课 现在不管什么GIS平台首先要解决的就是数据来源问题,因为没有数据的GIS就是一个空壳,下面我就目前一些主流的数据获取 方式了解做如下之我见(主要针对互联网上的一些…

Linux之Shell概述

目录 Linux之Shell概述 学习shell的原因 shell是什么 shell起源 查看当前系统支持的shell 查看当前系统默认shell Shell 概念 Shell 程序设计语言 Shell 也是一种脚本语言 用途 Shell脚本的基本元素 基本元素构成: Shell脚本中的注释和风格 Shell脚本编…

期货基础知识

一、期货是什么?  期货是与现货相对应,并由现货衍生而来。期货通常指期货合约,期货与现货完全不同,现货是实实在在可以交易的货(商品),期货主要不是货,而是以某种大众产品如棉花、大…

2023-大数据应用开发-工业数据实时处理-参考结果

工业数据实时处理-答案 任务一:实时数据采集 1、 在主节点使用Flume采集/data_log目录下实时日志文件中的数据,将数据存入到Kafka的Topic中(Topic名称分别为ChangeRecord、ProduceRecord和EnvironmentData,分区数为4&#xff09…

vue响应式详解

1. 响应式的定义 我们都知道,vue是基于javascript的,那我们使用一段javascript代码来描述响应式 let a 1,b 1,c; c a b; console.log(c) // 输出 2 // 改变 a的值 a 3; // 重新给c赋值 即把 c a b; 再执行一遍c的值才能变为 4 // c a b; // …