Java那些鲜为人知的关键字volatile详析

 更新时间:2021年03月05日 10:16:48   作者:Carson_Ho  
这篇文章主要给大家介绍了关于Java那些鲜为人知的关键字volatile的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在Java中,Java中volatile关键字十分重要

本文全面 & 详细解析volatile关键字,希望你们会喜欢

目录

1. 定义

Java 中的1个关键字 / 修饰符

2. 作用

保证 被 volatile修饰的共享变量 的可见性 & 有序性,但不保证原子性

3. 具体描述

下面,我将详细讲解 volatile是如何保证 “共享变量 的可见性 & 有序性,但不保证原子性”的具体原理

储备知识:原子性、可见性 & 有序性

3.1 保证可见性

具体描述

volatile修饰的属性保证每次读取都能读到最新的值

但不会 & 无法更新已经读了的值

原理

线程A在工作内存中修改的共享属性值会立即刷新到主存,线程B/C/D每次通过读写栅栏来达到类似于直接从主存中读取属性值

只是类似,网上有些说volatile修饰的变量读写直接在主存中操作,这种说法是不对的,只是表现出类似的行为

读写栅栏是一条CPU指令;插入一个读写栅栏 = 告诉CPU & 编译器先于这个命令的必须先执行,后于这个命令的必须后执行(有序性)

读写栅栏另一个作用是强制更新一次不同CPU的缓存。例如,一个写栅栏会 把这个栅栏前写入的数据刷新到缓存,以此保证可见性

3.2 保证有序性

具体描述

当对volatile修饰的属性进行读/写操作时,其前面的代码必须已执行完成 & 结果对后续的操作可见

原理

重排序时,以volatile修饰属性的读/写操作代码行为分界线,读/写操作前面的代码不许排序到后面,后面同理不许排序到前面。由此保证有序性

3.3 不保证原子性

具体描述

volatile修饰的属性若在修改前已读取了值,那么修改后,无法改变已经复制到工作内存的值

即无法阻止并发的情况

原理

// 变量a 被volatile修饰 
volatile static int a=0;
a++;
// 包含了2步操作:1 = 读取a、2= 执行a+1 & 将a+1结果赋值给a
// 设:线程A、B同时执行以下语句,线程A执行完第1步后被挂起、线程B执行了a++,那么主存中a的值为1
// 但线程A的工作内存中还是0,由于线程A之前已读取了a的值 = 0,执行a++后再次将a的值刷新到主存 = 1
// 即 a++执行了2次,但2次都是从0变为1,故a的值最终为1

4. 应用场

由于volatile保证可见性和有序性,被volatile修饰的共享属性一般并发读/写没有问题,可看做是一种轻量级的synchronized实现

关于synchronized的讲解具体请看文章:Java:这是一份全面 & 详细的 Synchronized关键字 学习指南

至此,关于Java中的volatile关键字讲解完毕。

5. 总结

本文主要讲解了Java中volatile关键字,其作用为 保证 “共享变量 的可见性 & 有序性,具体总结如下:

到此这篇关于Java那些鲜为人知的关键字volatile的文章就介绍到这了,更多相关Java关键字volatile内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring中常用注解的用法

    Spring中常用注解的用法

    这篇文章主要介绍了Spring中常用注解的用法,Spring注解方式减少了配置文件内容,更加便于管理,并且使用注解可以大大提高了开发效率,注解本身是没有功能的,和xml一样,注解和xml都是一种元数据,元数据即解释数据的数据,也就是所谓的配置,需要的朋友可以参考下
    2023-08-08
  • 详解Spring 基于 Aspect 注解的增强实现

    详解Spring 基于 Aspect 注解的增强实现

    本篇文章主要介绍了详解Spring 基于 Aspect 注解的增强实现,非常具有实用价值,需要的朋友可以参考下
    2017-04-04
  • Java Validation Api如何实现自定义注解

    Java Validation Api如何实现自定义注解

    这篇文章主要介绍了Java Validation Api如何实现自定义注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • SpringBoot项目加载配置文件的6种方式小结

    SpringBoot项目加载配置文件的6种方式小结

    这篇文章给大家总结了六种SpringBoot项目加载配置文件的方式,通过@value注入,通过@ConfigurationProperties注入,通过框架自带对象Environment实现属性动态注入,通过@PropertySource注解,yml外部文件,Java原生态方式注入这六种,需要的朋友可以参考下
    2023-09-09
  • 使用java web 在jsp文件及Class中连接MySQL和SQLserver 的驱动方法

    使用java web 在jsp文件及Class中连接MySQL和SQLserver 的驱动方法

    这篇文章主要介绍了使用java web 在jsp文件及Class中连接MySQL和SQLserver的驱动方法的相关资料,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
    2016-10-10
  • Java实现快速排序算法的完整示例

    Java实现快速排序算法的完整示例

    这篇文章主要给大家介绍了关于Java实现快速排序算法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Java实现数据库连接池简易教程

    Java实现数据库连接池简易教程

    这篇文章主要为大家介绍了Java实现数据库连接池简易教程,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • Java常用工具类—集合排序

    Java常用工具类—集合排序

    这篇文章主要介绍了Java集合排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • maven下mybatis-plus和pagehelp冲突问题的解决方法

    maven下mybatis-plus和pagehelp冲突问题的解决方法

    这篇文章主要介绍了maven下mybatis-plus和pagehelp冲突的解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • Spring cloud 查询返回广告创意实例代码

    Spring cloud 查询返回广告创意实例代码

    在本篇文章里小编给大家整理的是关于Spring cloud 查询返回广告创意实例代码,需要的朋友们可以跟着学习下。
    2019-08-08

最新评论