java中的 关键词vali_Java中的关键字volatile详解
volatile关键字经常用来修饰变量。不过,volatile本身很容易被误用。本篇就介绍一下volatile的原理和使用方式。
在介绍volatile关键字原理前,我们首先要了解JVM运行时的内存分配逻辑。
对于成员变量i,它存储在堆内存中。每个线程在运行时都会有一个自己的线程栈,线程如果要访问类的成员变量i,会通过引用获取到堆中变量i实际的值10,然后把这个变量值拷贝到自己的栈内存中,作为一个变量副本,之后线程便不再会与堆中的变量有实际联系。每个线程都有一个自己的本地副本,相互隔离。线程访问自己栈内存的效率比访问堆的效率高。线程对变量i值的修改,只会修改自己线程副本中的值,修改结束后,在线程退出前,会把自己线程副本中的值,刷新到堆中。
保证内存可见性
对于如下代码:
public class VolatileTest implements Runnable{
//volatile
private static boolean flag = false;
@Override
public 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初始化。
以上所述是小编给大家介绍的Java中的关键字volatile详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
java中的 关键词vali_Java中的关键字volatile详解相关推荐
- C语言:关键字volatile详解!
一.volatile 介绍 参看:volatile详解 参看:C Language Keywords Indicates that a variable can be changed by a bac ...
- JAVA中希尔排序去的讲解_java 中基本算法之希尔排序的实例详解
java 中基本算法之希尔排序的实例详解 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shel ...
- java中属性文件读取案例_java相关:Spring中属性文件properties的读取与使用详解
java相关:Spring中属性文件properties的读取与使用详解 发布于 2020-6-3| 复制链接 摘记: Spring中属性文件properties的读取与使用详解实际项目中,通常将一些 ...
- Java中print、printf、println的区别 详解
Java中print.printf.println的区别详解 printf主要是继承了C语言的printf的一些特性,可以进行格式化输出 print就是一般的标准输出,但是不换行 println和pr ...
- python中为什么推荐使用with_Python中的with关键字使用详解
这篇文章主要介绍了Python 中的with关键字使用详解的相关资料,在Python中,with关键字是一个替你管理实现上下文协议对象的好东西,需要的朋友可以参考下 "> 在 Pyth ...
- C++中const关键字用法详解及实例和源码下载(一)
最近在学习C++基础部分,看了两天书,已经看过了一遍,半知半解,回过头来重新看第二遍,深入了解一下C++的基础知识.现在读到了const关键字的用法,书上面讲解的时候并没有给出完整的实例,只是理论的讲 ...
- JAVA中的类和对象之this的详解
系列文章目录 第一章 JAVA中的类和对象之this的详解 目录 前言 一.为什么要有this引用 二.this的三种用法 1.this.成员变量 2.this.成员方法 3.this()调用其它的构 ...
- 站长在线Python教程精讲:在Python函数中的关键字参数详解
欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python函数中的关键字参数详解>.本文的主要内容有:关键字参数的含义和关键字参数的应用举例. 目录 1.关键字参数的含 ...
- java 串口 dtr rts_串口(RS232 RS485等)通讯中RTS/CTS,DTR/DSR的含义详解
串口(RS232 RS485等)通讯中RTS/CTS,DTR/DSR的含义详解 先贴出缩写的含义: DTR – Data Terminal Ready DSR – Data Set Ready RTS ...
- 【java】java 关键字: synchronized详解
1.概述 转载:关键字: synchronized详解 [Java]Synchronized 有几种用法 [java] 从hotspot底层对象结构理解锁膨胀升级过程 [java]动态高并发时为什么推 ...
最新文章
- JavaScript初学者编程题(21)
- 如何使用Cisco命令阻止访问特定网站
- 十二年 10 次 IT 大考 猪八戒网的系统架构和开发流程经历了什么?
- 帆软日期控件变灰_FineReport-JS脚本常见日期使用整理
- android开发国内镜像
- 实现省市二级联动效果
- 【转】Snackbar和Toast的花式使用,这一篇就够了
- linux如何查看jupyter日志_在Linux服务器上运行Jupyter notebook server教程
- Character Studio
- 树莓派+android things+实时音视频传输demo之遥控小车
- 敏捷外包工程系列之三:固定合同(敏捷外包工程,敏捷开发,产品负责人,客户价值)...
- beautifulsoup解析动态页面div未展开_实战|Python轻松实现动态网页爬虫(附详细源码)...
- 【sklearn第二十七讲】模型持久性
- [导入]基于D3D Effect的引擎模式探讨。
- 2021年BATJ30套大厂Android经典高频面试题,附答案
- 深度学习之稀疏编码小知识
- rebase操作步骤
- 计算机网络交换机无法ping,无法Ping通路由器交换机提示request time out修复方法
- linux pptpd源码,Centos 7 源码安装pptpd
- 王牌竞速安装后显示服务器维护,王牌竞速进不去游戏怎么办 如何解决进不去游戏...