Java并发面试问题之volatile到底是什么?
本文转载自公众号:石杉的架构笔记,阅读大约需要7分钟。
一、写在前面
前段时间把几年前带过的一个项目架构演进的过程整理了一个系列出来,参见(《亿级流量架构系列专栏总结》)。
不过很多同学看了之后,后台反馈说文章太烧脑,看的云里雾里。其实这个也正常,文章承载的信息毕竟有限,而架构的东西细节太多,想要仅仅通过文章看懂一个系统架构的设计和落地,确实难度不小。
所以接下来用大白话跟大家聊点轻松的话题,比较易于理解,而且对大家工作和面试都很有帮助。
二、场景引入,问题初现
第一,一旦data变量定义的时候前面加了volatile来修饰的话,那么线程1只要修改data变量的值,就会在修改完自己本地工作内存的data变量值之后,强制将这个data变量最新的值刷回主内存,必须让主内存里的data变量值立马变成最新的值!
整个过程,如下图所示:
2
第二,如果此时别的线程的工作内存中有这个data变量的本地缓存,也就是一个变量副本的话,那么会强制让其他线程的工作内存中的data变量缓存直接失效过期,不允许再次读取和使用了!
整个过程,如下图所示:
3
第三,如果线程2在代码运行过程中再次需要读取data变量的值,此时尝试从本地工作内存中读取,就会发现这个data = 0已经过期了!
此时,他就必须重新从主内存中加载data变量最新的值!那么不就可以读取到data = 1这个最新的值了!整个过程,参见下图:
bingo!好了,volatile完美解决了java并发中可见性的问题!
对一个变量加了volatile关键字修饰之后,只要一个线程修改了这个变量的值,立马强制刷回主内存。
接着强制过期其他线程的本地工作内存中的缓存,最后其他线程读取变量值的时候,强制重新从主内存来加载最新的值!
这样就保证,任何一个线程修改了变量值,其他线程立马就可以看见了!这就是所谓的volatile保证了可见性的工作原理!
四、总结 & 提醒
最后给大家提一嘴,volatile主要作用是保证可见性以及有序性。
有序性涉及到较为复杂的指令重排、内存屏障等概念,本文没提及,但是volatile是不能保证原子性的!
也就是说,volatile主要解决的是一个线程修改变量值之后,其他线程立马可以读到最新的值,是解决这个问题的,也就是可见性!
但是如果是多个线程同时修改一个变量的值,那还是可能出现多线程并发的安全问题,导致数据值修改错乱,volatile是不负责解决这个问题的,也就是不负责解决原子性问题!
原子性问题,得依赖synchronized、ReentrantLock等加锁机制来解决。
下方查看历史文章
99.9%的Java程序员都说不清的问题:JVM中的对象内存布局?
本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。
Java并发面试问题之volatile到底是什么?的更多相关文章
- 并发系列1----大白话聊聊Java并发面试问题之volatile到底是什么?【石杉的架构笔记】
- Java并发编程之三:volatile关键字解析 转载
目录: <Java并发编程之三:volatile关键字解析 转载> <Synchronized之一:基本使用> volatile这个关键字可能很多朋友都听说过,或许也都用过 ...
- Java并发编程之验证volatile不能保证原子性
Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...
- Java并发编程学习:volatile关键字解析
转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...
- java并发面试
1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...
- Java并发编程基础之volatile
首先简单介绍一下volatile的应用,volatile作为Java多线程中轻量级的同步措施,保证了多线程环境中“共享变量”的可见性.这里的可见性简单而言可以理解为当一个线程修改了一个共享变量的时候, ...
- 干货:Java并发编程系列之volatile(二)
接上一篇<Java并发编程系列之synchronized(一)>,这是第二篇,说的是关于并发编程的volatile元素. Java语言规范第三版中对volatile的定义如下:Java编程 ...
- Java并发编程里的volatile。Java内存模型核CPU内存架构的对应关系
CPU内存架构:https://www.jianshu.com/p/3d1eb589b48e Java内存模型:https://www.jianshu.com/p/27a9003c33f4 多线程下的 ...
随机推荐
- lower_case_table_names=1 启动报错 mysql8.0
我们知道在 Linux 环境下默认是区分大小写的,所以我们需要改变这种默认方式,经过网上各种搜索后,基本就是清一色的修改 lower_case_table_names,然后信誓旦旦的去修改了,但是修改 ...
- es4x 引用外部jar 包以及集成typescrip
以前写过一个通过修改jar 包处理自定义jar 的引入的,如下是一种使用官方推荐的方法package.json 添加依赖配置 同时为了方便使用添加typescript define 文件方便使用(只是 ...
- 转载:tensorflow保存训练后的模型
训练完一个模型后,为了以后重复使用,通常我们需要对模型的结果进行保存.如果用Tensorflow去实现神经网络,所要保存的就是神经网络中的各项权重值.建议可以使用Saver类保存和加载模型的结果. 1 ...
- 编译udf小软件(附视频教程)
小软件下载地址(不仅支持Visual Studio并且打包gcc,解压即可编译): https://pan.baidu.com/s/1XPfjfY8DC2KKS8gj1KhutQ 提取码: 6kju ...
- java calendar获取系统当前小时数
calendar获取系统当前小时数 24小时制 Calendar calendar = Calendar.getInstance(); int curHour24 = calendar.get(c ...
- js追加html元素
jquery追加html代码,添加元素 .append() //新增仲裁申请人 $("."+inputName).append("<div class=\" ...
- 2018-2019-2 网络对抗技术 20165230 Exp9 :Web安全基础
目录 实验目的 实验内容 Webgoat前期准备 出现的问题 (一)SQL注入攻击 命令注入:Command Injection 数字型注入:Numeric SQL Injection 日志欺骗:Lo ...
- 【C/C++开发】C++11 并发指南三(std::mutex 详解)
本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ...
- Nginx配置反向代理支持WebSocket
http { #WebSocket代理配置 map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { ...
- Faiss的学习和入门文章
可以看这里的文章: https://www.leiphone.com/news/201703/84gDbSOgJcxiC3DW.html https://waltyou.github.io/Faiss ...