Java中的关键字--volatile
volatile关键字经常用来修饰变量。不过,volatile本身很容易被误用。本篇就介绍一下volatile的原理和使用方式。
在介绍volatile关键字原理前,我们首先要了解JVM运行时的内存分配逻辑。
对于成员变量i,它存储在堆内存中。每个线程在运行时都会有一个自己的线程栈,线程如果要访问类的成员变量i,会通过引用获取到堆中变量i实际的值10,然后把这个变量值拷贝到自己的栈内存中,作为一个变量副本,之后线程便不再会与堆中的变量有实际联系。每个线程都有一个自己的本地副本,相互隔离。线程访问自己栈内存的效率比访问堆的效率高。线程对变量i值的修改,只会修改自己线程副本中的值,修改结束后,在线程退出前,会把自己线程副本中的值,刷新到堆中。
保证内存可见性
对于如下代码:
public class VolatileTest implements Runnable{ //volatileprivate static boolean flag = false;@Overridepublic void run() {while (!flag){System.out.println(Thread.currentThread().getName() +"执行中");}System.out.println(Thread.currentThread().getName() +"执行完毕");}//main线程public static void main(String[] args) throws InterruptedException {new Thread(new VolatileTest(), "支线程Volatile").start();Thread.sleep(1000);flag = true;}}
大多数时候可以正常中断,但是一旦发送异常,便会导致线程死循环。所以需要在flag标志上加一个volatile关键字。对于加了volatile关键字的变量值,线程1修改了这个值的话,会强制将修改值直接写入堆内存中,其他线程各自线程栈中的变量副本无效,只能去堆中取最新的变量值。多个线程之间的内存可见得以保证。
值得注意的是,volatile关键字不能保证原子性。
private volatile int i;i++;
i ++ 这个操作涉及到获取值,自增和赋值3部分。无法直接完成。上面想要以volatile来实现原子性的写法是错误的。
禁止指令重排
现代JVM对代码的执行顺序有一定的优化。例如:
int a = 4; int b = 5; int c = a + b;
上面3条指令进过JVM优化以后,时间的执行顺序不一定是从上到下,有可能是 第二条--->第一条-->第三条。总之不会影响最终执行结果。
但是在多线程情况下,如下代码就会有风险:
//线程1: context = loadContext(); inited = true; //线程2: while(!inited ){} doSomething(context);
线程1的两条语句之间没有依赖性,经过指令重排后,有可能inited置为true以后,context还没有初始化。线程2发现inited为true,以为初始化完成,结束循环,用时间还没有初始化的context去执行doSomething()方法。报错。所以我们可以用volatile关键字修饰inited,保证context初始化。
转载于:https://www.cnblogs.com/sunshine-ground-poems/p/10309201.html
Java中的关键字--volatile相关推荐
- Java中的关键字volatile解析
volatile是研究Java并发编程绕不过去的一个关键字,先说结论: volatile的作用: 1.保证被修饰变量的可见性 2.保证程序一定程度上的有序性 3.不能保证原子性 下面,我们将从理论以及 ...
- java 死锁 内存消耗_详解Java中synchronized关键字的死锁和内存占用问题
先看一段synchronized 的详解: synchronized 是 java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并 ...
- [转载] Java中的关键字含义以及介绍
参考链接: C++和Java中static关键字的比较 Java关键字是有特别意义的标识符.用来表示一种数据类型,或者表示程序的结构等. Java关键字不能用作变量名.方法名.类名.包名和参数. 以下 ...
- java中的关键字英汉
java中的关键字 初入java记录贴 类: enum(枚举).interface(接口).class(类).extends(继承).implements(实现接口) 对象: new(创建).inst ...
- Java中synchronized和volatile有什么区别?
Java中synchronized和volatile有什么区别? 相关内容 synchronized的问题 什么叫做不完整对象,这个怎么理解呢? 总结 ) 相关内容 1.Java语言为了解决并发编程中 ...
- 【Java_基础】Java中Native关键字的作用
本篇博文转载与:Java中Native关键字的作用 转载于:https://www.cnblogs.com/leiblog/p/10529056.html
- java中final关键字的使用
final 中文翻译为 最终的,在java中也是较为常用的关键字之一. 在java 中 final 关键字可以修饰 类.方法.变量 final 修饰在类上,则表示该类不能被继承,如果里面的成员变量没 ...
- java中的关键字static
原文链接: https://zhuanlan.zhihu.com/p/70110497 昨晚面试中被问到,没能回答出来.这篇答疑文章写得非常好,无一字可增删,遂直接复制. 在平时开发当中,我们经常会遇 ...
- java transient_【转】Java中的关键字 transient
阅读目录 先解释下Java中的对象序列化 在讨论transient之前,有必要先搞清楚Java中序列化的含义: Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的 ...
最新文章
- [windows server 2008 站点系列五]一招加速域用戶的文件查找速度
- POJ-2481 Cows---树状数组的运用
- ITK:切割网格CutMesh
- MySQL之三范式:原子性 唯一性 避免数据冗余
- 基于 Python 自建分布式高并发 RPC 服务
- 动态规划——物品无限的背包问题
- 受半导体短缺及疫情影响,丰田已下调9月10月及当前财年产量预期
- json格式的简单转换
- 在.NET 3.5 平台上使用LINQ to SQL创建三层/多层Web应用系统(源代码下载和PDF文档下载)...
- Linux用户-政府篇
- 智能车四轮组打工日记(二)——单电机驱动硬件设计
- java算法2——费氏数列
- Mybatis之分页插件PageHelper工作原理
- MySQL查看锁及事务隔离级别的命令
- 柬埔寨吴哥旅游:并不仅仅是神秘
- x264 i_thead
- 一个屌丝程序员的青春(一三八)
- Web全栈~26.IO
- 安装mavros时,运行 wstool update -t src -j8 时出错解决
- opencv python gpu加速_OpenCV中配置CUDA,实现GPU加速
热门文章
- vue2.0中组建里面套用组件_vue19 组建 Vue.extend component、组件模版、动态组件 的实例代码...
- php imagefill,PHP图像处理技术实例总结【绘图、水印、验证码、图像压缩】
- 电脑测试软件_科普丨电脑小白必看的显卡测试小技巧
- asm扩容流程_AIX之ASM存储扩容
- web集成axis2_AXIS2 Web服务教程
- maven安装junit_JUnit安装Maven – JUnit 4和JUnit 5
- Django ModelForms
- 析构函数c+_了解C ++中的析构函数
- C# 窗体全透明,控件不透明
- Android Studio 修改项目包名(Xposed)