iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >Java中Volatile变量有什么用
  • 901
分享到

Java中Volatile变量有什么用

2023-06-25 11:06:33 901人浏览 独家记忆
摘要

这篇文章将为大家详细讲解有关Java中Volatile变量有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Volatile关键字是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步

这篇文章将为大家详细讲解有关Java中Volatile变量有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

    Volatile关键字是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量, 相比synchronized(synchronized通常称为重量级),volatile更轻量级,因为它不会引起线程上下文的切换和调度。 但是volatile 变量的同步性较差(有时它更简单并且开销更低),而且其使用也更容易出错。

    一、volatile变量的特性

    1.1、保证可见性,不保证原子性

    • 当写一个volatile变量时,JMM会把该线程本地内存中的变量强制刷新到主内存中去;

    • 这个写会操作会导致其他线程中的volatile变量缓存无效。

    来看一段代码:

    public class Test {    public static void main(String[] args) {        WangZai wangZai = new WangZai();        wangZai.start();        for(; ;){            if(wangZai.isFlag()){                System.out.println("hello");            }        }    }     static class WangZai extends Thread {         private boolean flag = false;         public boolean isFlag(){            return flag;        }         @Override        public void run() {            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            flag = true;            System.out.println("flag = " + flag);        }    }}

    你会发现,永远都不会输出hello这一段代码,按道理线程改了flag变量,主线程也能访问到的呀?

    但是将flag变量用volatile修饰一下,就能输出hello这段代码

    private volatile boolean flag = false;

    每个线程操作数据的时候会把数据从主内存读取到自己的工作内存,如果他操作了数据并且写会了,那其他已经读取的线程的变量副本就会失效了,需要对数据进行操作又要再次去主内存中读取了。

    volatile保证不同线程对共享变量操作的可见性,也就是说一个线程修改了volatile修饰的变量,当修改写回主内存时,另外一个线程立即看到最新的值。

    1.2、禁止指令重排

    排序需要遵守一定规则:

    • 重排序操作不会对存在数据依赖关系的操作进行重排序。

    • 重排序是为了优化性能,但是不管怎么重排序,单线程下程序的执行结果不能被改变。

    什么是重排序?

    为了提高性能,编译器和处理器常常会对既定的代码执行顺序进行指令重排序。

    重排序的类型有哪些呢?

    Java中Volatile变量有什么用

    一个好的内存模型实际上会放松对处理器和编译器规则的束缚,也就是说软件技术和硬件技术都为同一个目标,而进行奋斗:在不改变程序执行结果的前提下,尽可能提高执行效率。

    JMM对底层尽量减少约束,使其能够发挥自身优势。

    因此,在执行程序时,为了提高性能,编译器和处理器常常会对指令进行重排序。

    一般重排序可以分为如下三种:

    • 编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序;

    • 指令级并行的重排序。现代处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序;

    • 内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行的。

    那 Volatile 是怎么保证不会被执行重排序的呢?

    二、内存屏障

    java编译器会在生成指令系列时在适当的位置会插入内存屏障指令来禁止特定类型的处理器重排序。

    为了实现volatile的内存语义,JMM会限制特定类型的编译器和处理器重排序,JMM会针对编译器制定volatile重排序规则表:

    是否能重排序第二个操作第一个操作普通读/写volatile读volatile写普通读/写NOvolatile读NONONOvolatile写NONO

    举例来说,第三行最后一个单元格的意思是:在程序顺序中,当第一个操作为普通变量的读或写时,如果第二个操作为volatile写,则编译器不能重排序这两个操作。

    从上表我们可以看出:

    • 当第二个操作是volatile写时,不管第一个操作是什么,都不能重排序。这个规则确保volatile写之前的操作不会被编译器重排序到volatile写之后。

    • 当第一个操作是volatile读时,不管第二个操作是什么,都不能重排序。这个规则确保volatile读之后的操作不会被编译器重排序到volatile读之前。

    • 当第一个操作是volatile写,第二个操作是volatile读时,不能重排序。

    需要注意的是:volatile写是在前面和后面分别插入内存屏障,而volatile读操作是在后面插入两个内存屏障。

    Java中Volatile变量有什么用

    Java中Volatile变量有什么用

    jdk5开始,提出了happens-before的概念,通过这个概念来阐述操作之间的内存可见性。

    三、happens-before

    happens-before 关系的定义:

    • 如果一个操作 happens-before 另一个操作,那么第一个操作的执行结果就会对第二个操作可见。

    • 两个操作之间如果存在 happens-before 关系,并不意味着 Java 平台的具体实现就必须按照 happens-before 关系指定的顺序来执行。如果重排序之后的执行结果,与按照 happens-before 关系来执行的结果一直,那么 JMM 也允许这样的重排序。

    看到这儿,你是不是觉得,这个怎么和 as-if-serial 语义一样呢。没错, happens-before 关系本质上和 as-if-serial 语义是一回事。

    as-if-serial 语义保证的是单线程内重排序之后的执行结果和程序代码本身应该出现的结果是一致的,

    happens-before 关系保证的是正确同步的多线程程序的执行结果不会被重排序改变。

    一句话来总结就是:如果操作 A happens-before 操作 B ,那么操作 A 在内存上所做的操作对操作 B 都是可见的,不管它们在不在一个线程。

    在 Java 中,对于 happens-before 关系,有以下规定:

    • 程序顺序规则:一个线程中的每一个操作, happens-before 于该线程中的任意后续操作。

    • 监视器锁规则:对一个锁的解锁, happens-before 于随后对这个锁的加锁。

    • volatile 变量规则:对一个 volatile 域的写, happens-before 与任意后续对这个 volatile 域的读。

    • 传递性:如果 A happens-before B , 且 B happens-before C ,那么 A happens-before C。

    • start 规则:如果线程 A 执行操作 ThreadB。start() 启动线程 B ,那么 A 线程的 ThreadB。start() 操作 happens-before 于线程 B 中的任意操作。

    • join 规则:如果线程 A 执行操作 ThreadB。join() 并成功返回,那么线程 B 中的任意操作 happens-before 于线程 A 从 ThreadB。join() 操作成功返回。

    关于“Java中Volatile变量有什么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

    --结束END--

    本文标题: Java中Volatile变量有什么用

    本文链接: https://www.lsjlt.com/news/304353.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Java中Volatile变量有什么用
      这篇文章将为大家详细讲解有关Java中Volatile变量有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Volatile关键字是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步...
      99+
      2023-06-25
    • java中volatile变量的原理是什么
      这篇文章给大家介绍java中volatile变量的原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. 客户端开发;4. 网...
      99+
      2023-06-14
    • Java中volatile关键字有什么用
      这篇文章将为大家详细讲解有关Java中volatile关键字有什么用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。概述Java语言中关键字 volatile 被称作轻量级的 synchron...
      99+
      2023-06-19
    • Java中的volatile关键字有什么用
      本篇内容主要讲解“Java中的volatile关键字有什么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中的volatile关键字有什么用”吧!一、volatile作用可以保证多线程环...
      99+
      2023-06-30
    • Java中局部变量和成员变量有什么区别
      今天小编给大家分享的是Java中局部变量和成员变量有什么区别,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。目录一. 关于变量 概念 命名规范 作用范围 变量分类二. 局部变量 概念 ...
      99+
      2023-07-06
    • java中volatile变量并发操作的示例分析
      小编给大家分享一下java中volatile变量并发操作的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java的特点有哪些Java的特点有哪些1.Jav...
      99+
      2023-06-14
    • java home环境变量有什么作用
      Java Home环境变量是Java开发环境中非常重要的一个环境变量,它的作用主要有以下几点: 指定Java运行时的安装路径:J...
      99+
      2024-03-04
      java
    • Java中怎么使用volatile
      这篇文章主要介绍了Java中怎么使用volatile的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java中怎么使用volatile文章都会有所收获,下面我们一起来看看吧。 ...
      99+
      2024-04-02
    • java中什么是类变量
      本篇文章为大家展示了java中什么是类变量,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. 客户端开发;4. ...
      99+
      2023-06-14
    • Java并发编程中volatile关键字有什么作用
      本篇内容主要讲解“Java并发编程中volatile关键字有什么作用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java并发编程中volatile关键字有什么作用”吧!1、volatile是什...
      99+
      2023-06-25
    • Java并发编程之Volatile变量详解分析
      目录一、volatile变量的特性1.1、保证可见性,不保证原子性1.2、禁止指令重排二、内存屏障三、happens-beforeVolatile关键字是Java提供的一种轻量级的同...
      99+
      2024-04-02
    • VB.NET变量有什么用
      这篇文章主要为大家展示了“VB.NET变量有什么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“VB.NET变量有什么用”这篇文章吧。VB.NET变量用来存储程序中需要处理的数据,用户可以把变量...
      99+
      2023-06-17
    • java环境变量配置有什么作用
      java环境变量配置的作用有:1、找到JDK的安装路径;2、允许全局访问Java命令;3、简化编译和运行Java程序;4、提高开发效率。Java 环境变量配置的作用主要体现在以下几个方面:找到 JDK 的安装路径:通过配置 JAVA_HOM...
      99+
      2023-07-31
    • java配置jdk环境变量有什么用
      java配置jdk环境变量能够让我们在命令行或终端中执行Java程序,编译Java源代码,导入Java库,并使用一些Java开发工具。通过正确配置环境变量,我们可以更加方便地进行Java开发,提高开发效率和代码质量。因此,学习如何配置JDK...
      99+
      2023-08-01
    • java成员变量和局部变量有什么区别
      Java中的成员变量和局部变量有以下区别:1. 作用域不同:成员变量在整个类中都可见,而局部变量只在声明它的代码块内可见。2. 生命...
      99+
      2023-08-23
      java
    • Java中变量怎么用
      小编给大家分享一下Java中变量怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!public class TestVariable{pub...
      99+
      2023-06-02
    • java中什么是实例变量
      java中什么是实例变量?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. 客户端开发...
      99+
      2023-06-14
    • java中什么是局部变量
      今天就跟大家聊聊有关java中什么是局部变量,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系...
      99+
      2023-06-14
    • 静态变量有什么用
      静态变量是一种在程序运行期间保持固定存储位置的变量,有以下几个主要的用途:1、实现对数据的持久性存储和访问;2、在程序的不同部分之间共享数据;3、用于保存函数的状态信息;4、用于控制函数或类成员的可见性和范围。本教程操作系统:Windows...
      99+
      2023-08-17
    • C语言中volatile 关键字有什么用
      这期内容当中小编将会给大家带来有关C语言中volatile 关键字有什么用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、关键字 volatile 是什么volatile是一个类型修饰符(type sp...
      99+
      2023-06-16
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作