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

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.lryc.cn/news/158584.html

相关文章:

  • ​Vue + Element UI前端篇(二):Vue + Element 案例 ​
  • Qt5中connect信号槽无效问题 C++
  • 服务端 TCP 连接的 TIME_WAIT 过多问题的分析与解决
  • 【Unity3D赛车游戏优化篇】【十】汽车粒子特效和引擎咆哮打造极速漂移
  • 肖sir__设计测试用例方法之编写测试用例12
  • Android 11.0 ota升级之Systemui下拉状态栏quick_settings_tiles_default值减少时更新的功能实现
  • Android Studio中创建java项目
  • 冠达管理:“旺季”来临,煤炭板块走高,云煤能源、陕西黑猫涨停
  • 【EI检索】第四届公共卫生与数据科学国际学术研讨会(ICPHDS 2023)
  • 对时序数据进行分类与聚类
  • Win10如何找回图片查看器
  • 【脑机接口】基于运动想象的康复指导在脑卒中偏瘫患者中的应用
  • vue-cli中vuex下$store”未在实例上定义
  • AutoSAR配置与实践(实践篇)12.1 BSW WatchDog功能的配置和实现
  • 【UI自动化测试】Jenkins配置
  • C#使用DataTable的Select方法来选择特定的字段
  • 总结梳理HTTP状态码
  • MySQL 8.0(winx64)安装笔记
  • vue封装wangEditor
  • 【Spring Boot 源码学习】深入 FilteringSpringBootCondition
  • docker 笔记6:高级篇 DockerFile解析
  • 微信小程序navigateTo进入页面后返回原来的页面需要携带数据回来
  • Python照片压缩教程详解
  • 软路由的负载均衡设置:优化网络性能和带宽利用率
  • CH06_第一组重构(上)
  • RHCSA-VMware Workstation Pro-Linux基础配置命令
  • YOLO-NAS详细教程-姿势估计实现
  • 【扩散模型 李宏毅B站教学以及基础代码运用】
  • SpringBoot隐藏文件
  • 常见数据库介绍对比之SQL关系型数据库