JVM--指令重排序+volatile关键字

浩浩 等级 630 0 0
标签: volatileJava

volatile 关键字

1、 volatile 翻译为 不稳定的,容易改变的。意思很明确,如果使用volatile 定义一个变量,意思就是可能该变量改变频繁,并且设计到多线程访问问题。

2、不过 现在jdk 的synchronized关键字 性能已经足够出色,也提供了多种Lock 类,因此 volatile关键字能实现的功能 jdk 的同步方法都能够实现,也是非必须的,但是内容和原理我们还是要掌握的。

volatile 修饰 有三种作用

  • 可见性

对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入,意思就是 读取的一定是主内存中的最新值,

当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

  • 有序性

    JVM 在运行class文件指令时会对代码进行一些优化,对没有依赖关系的代码执行顺序不保证是按照代码编写执行的,但能保证最后的运行结果是一样的。所以会导致在多线程环境下造成程序运行异常。如下图所示:

JVM--指令重排序+volatile关键字

a、b、c、d 这4句代码 没有任何关联性,所以执行的时候 顺序不一定按图中所示执行。 意思就是 当执行到d=4 这句时 可能a 还未赋值。所以 jdk 在1.5 后优化了volatile 关键字。

JVM--指令重排序+volatile关键字

如上图,定义vo 使用 volatile 修饰。这样jvm可以保证在执行 vo = 5 这句时,a、b 一定是已经赋值的,c、d 一定是未赋值的,就相当于在中间加了一个屏障,,但是volatile 并不能保证 a b 和 c d 这两句之间的执行顺序。

  • 原子性

任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。volatile 只保证自己的读写 是原子性,但是不能保证 多个对自己的指令时原子的。

收藏
评论区

相关推荐

JVM--指令重排序+volatile关键字
volatile 关键字 1、 volatile 翻译为 不稳定的,容易改变的。意思很明确,如果使用volatile 定义一个变量,意思就是可能该变量改变频繁,并且设计到多线程访问问题。 2、不过 现在jdk 的synchronized关键字 性能已经足够出色,也提供了多种Lock 类,因此 volatile关键字能实现的功能 jdk 的同步方法都能够实
接手了严重过时的软件,到底是该逐步重构还是摧毁重写呢?
有一个应用程序充斥着技术债,严重的过时了,或者只是对用户服务不足,因此,我们需要了解我们的最佳选择是什么——是继续艰难地探索并逐步进行重构更有意义,还是把它全部摧毁并从头开始重写更有意义呢?这就是我们将在本文中探讨的基本难题。所以让我们开始吧…… 但是没有那么快!在我们进一步研究之前,需要解决一个大家“避而不谈”的问题,即:对于任何需要改进的遗留应用程序,
Java多态实现原理
Java多态概述 多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向派生类的对象,而在具体访问时实现方法的动态绑定。Java 对于方法调用动态绑定的实现主要依赖于方法表,但通过类引用调用(invokevirtual)和接口引用调用(invokeinterface)的实现则有所不同。 类引用调用的大致过程为:Java编译器将Java源代码编译成c
从 PHP 转到 Java
前言 最近主要编程语言从 PHP 转到了 Java。这一个多月的经历对我很有意义,所以写文章记录一下。 编程语言各有侧重,它们之间的比较没什么意义,所以本文只写一下我对两种语言的看法,以及我转到另一种语言的经历,再分享一下最近学习 Java 的心得体会。 文章欢迎转载,请尊重作者劳动成果,带上原文链接:http://www.cnblogs
Groovy初探
开始之前 了解本教程的主要内容,以及如何从中获得最大收获。 关于本教程 如果现在有人要开始完全重写 Java,那么 Groovy 就像是 Java 2.0。Groovy 并没有取代 Java,而是作为 Java 的补充,它提供了更简单、更灵活的语法,可以在运行时动态地进行类型检查。您可以使用 Groovy 随意编写 Java 应用程序,连接 Java
volatile 关键字说明
volatile 变量修饰的共享变量进行写操作前会在汇编代码前增加 lock 前缀: 1),将当前处理器缓存行的数据写回到系统内存; 2),这个写会内存的操作会使其它 cpu 缓存该内存地址的数据无效。 Java 语言 volatile 关键字可以用一句贴切的话来描述 “ 人皆用之,莫见其形 “。理解 volatile 对理解它对理解 Java
一篇文章弄懂Java多线程基础和Java内存模型
文章目录 一、多线程的生命周期及五种基本状态 二、Java多线程的创建及启动 1.继承Thread类,重写该类的run()方法 2.通过实现Runnable接口创建线程类 3.通过Callable和Future接口创建线程 三、Java内存模型概念 四、内存间的交互操作 五、volatile和synchronized的
葡萄酒指标实训 Python语言
本文所需数据下载地址——众所周知,葡萄酒的价格是与其品质相关的,本实训根据表中提供的数据对包葡萄酒品质数进行了分析与处理。| 变量名 | 含义 || | || fixed acidity | 固定酸度 || volatile acidity | 挥发性酸度 || citric acid | 柠檬酸 || residual sugar | 剩
一段代码被老大要求重构了六次,我心态崩了
前言Hi,大家好,我是麦洛。我又回来啦🙈进来给大家八卦一段,看看我自己都去干啥了?话说最近公司接了一个农产品交易网站新项目,因为一段代码重构问题差点和老大干起来,本来以为是老大故意刁难我。最后还是发现是我太菜了😏,事情是这个样子滴!在周例会上,老大告知我们最近接了一个农产品交易平台,主要用于全省农产品线上交易。首当其中,就是要把我们甘肃省的黄河蜜推销出去,我
Java TreeMultiSet-为什么要开发这个数据结构???
TreeMultiSet基于TreeMap实现的支持可重复元素的TreeSet搞过java的人应该都知道TreeSet,但是TreeSet是不支持重复元素的。有人会说,那用ArrayList或LinkedList不就可以了吗?确实,ArrayList或LinkedList天然不去重,可以满足支持重复元素的需求。但是,我不仅需要支持可重复元素,而且需要数据实时
2021年度最全面JVM虚拟机,类加载过程与类加载器
前言类装载器子系统是JVM中非常重要的部分,是学习JVM绕不开的一关。一般来说,Java 类的虚拟机使用 Java 方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表
阿里一线架构师技术图谱!十年开发经验Java架构师
开头我们面试的时候 ,经常会被问这种到问题:Spring中bean的循环依赖怎么解决? Spring中bean的加载过程? spring相关的问题一直是大厂面试常问到的一个问题,也是一直困扰这我们,不知道从哪里下手,今天举例分析大厂的一些spring相关的面试真题。和分享我学习spring相关问题所整理的一些知识点。 01 并发宝典:面试专题面试专题分为四个
2021年度最全面JVM虚拟机,类加载过程与类加载器
前言类装载器子系统是JVM中非常重要的部分,是学习JVM绕不开的一关。一般来说,Java 类的虚拟机使用 Java 方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表
阿里Java架构师谈:2021年最新Java面试经历
第一家是美团美团的话,三面下来,设计的内容知识也是挺广的吧,有MySQL、Redis、Kafka、线程、算法、+、volatile、线程、并发、设计模式等等... 一面问题:MySQL+Redis+Kafka+线程+算法 mysql知道哪些存储引擎,它们的区别 mysql索引在什么情况下会失效 mysql在项目中的优化场景,慢查询解决等 my
一次性带你了解清楚Java内存模型!
[Java 内存模型]咳咳咳,能看完的都是人上人。。。。Java 虚拟机内部使用 JMM(Java 内存模型) 将内存划分为两个逻辑单元,线程栈(或者叫本地内存)和堆。每一个线程都有属于自己的线程栈,在线程栈中会保存局部变量(也叫做本地变量)、方法中定义的参数和异常处理器的参数(catch中的参数);这些参数和变量都属于线程局部操作,会被隔离,所以不受内存模