Java中的volatile关键字解析

 更新时间:2023年11月01日 08:38:01   作者:南瓜灯cc  
这篇文章主要介绍了Java中的volatile关键字解析,Java内存模型规定了所有的变量都存储在主内存中,每个线程都有自己的工作内存,线程的工作内存保存了该线程使用到的变量的是主内存副本的拷贝,需要的朋友可以参考下

volatile关键字

在对该关键字进行认识之前,需要对Java内存模型有一定的认识。 Java内存模型规定了所有的变量都存储在主内存中,每个线程都有自己的工作内存,线程的工作内存保存了该线程使用到的变量的是主内存副本的拷贝,线程对于变量的操作(读取,复制)都必须在工作内存中进行,而不能直接读写主内存中的变量。

这里写图片描述

在进行变量操作的时候,如果每次都是从主内存中读写,无疑是影响性能的, 即一个线程在操作某一个变量之前,会先把变量的值从主内存中拷贝一个副本放到工作内存中,操作完成之后同步到主内存中。不同的线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。

volatile: 当一个变量被定义为volatile(不稳定的)之后,线程在进行变量操作的时候,都不会使用本地内存中之前缓存的数据,而是每次都会从主内存中把变量的值拷贝副本到工作内存中,这样就保证了变量对于所有线程的可见性。

public class TestVolatile {
     public static void main(String[] args) throws Exception {
         ThreadDemo td=new ThreadDemo();
         Thread t=new Thread(td);
         t.start();
         while(true){
             if(td.isFlag()){
                 System.out.println("OK");
                 break;
             }
         }
    }    
}

class ThreadDemo implements Runnable{
    private volatile boolean flag=false;
    @Override
    public void run() {
        try {
            Thread.sleep(2000); 
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag=true;
        System.out.println("flag="+isFlag());
    }


    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

需要特别注意的是, 即使volatile能够保证其变量对于线程的可见性,但是却不能保证并发的安全性。

比如多线程执行线程执行i++(i假设用volatilex修饰)也不能保证其安全性。 如下图:

这里写图片描述

因为i++并不是原子性的操作,当一个线程A再工作内存中进行数据操作的时候,还未结束的时候,cpu切换到了另一个线程B,而此时之前i++操作并没有结束,即并没有把数据刷新到主内存中,此时B获取到的数据跟A获取的数据实际上是一样的,这时候就存在了并发的问题了。

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

相关文章

  • Java基于redis实现分布式锁

    Java基于redis实现分布式锁

    系统的不断扩大,分布式锁是最基本的保障。今天我们介绍通过redis实现分布式锁,感兴趣的朋友可以参考下
    2021-05-05
  • Spring AOP 后置通知修改响应httpstatus方式

    Spring AOP 后置通知修改响应httpstatus方式

    这篇文章主要介绍了Spring AOP 后置通知修改响应httpstatus方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java中异常传播的实现

    Java中异常传播的实现

    在Java中,异常传播是一个重要的概念,本文主要介绍了Java中异常传播的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Maven构建SpringBoot集成MyBatis过程

    Maven构建SpringBoot集成MyBatis过程

    文章介绍了如何使用Maven创建一个Spring Boot项目,并集成MyBatis,首先,配置Maven环境,然后在pom.xml中添加MyBatis依赖,配置数据库连接信息,最后生成Mapper XML文件和DAO层代码
    2024-11-11
  • Spring Boot加密配置文件特殊内容的示例代码详解

    Spring Boot加密配置文件特殊内容的示例代码详解

    这篇文章主要介绍了Spring Boot加密配置文件特殊内容的相关知识,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • SpringBoot+ECharts是如何实现数据可视化的

    SpringBoot+ECharts是如何实现数据可视化的

    今天带大家学习的是关于Java的相关知识,文章围绕着SpringBoot+ECharts怎么实现数据可视化展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • IDEA+Maven打JAR包的两种方法步骤详解

    IDEA+Maven打JAR包的两种方法步骤详解

    Idea中为一般的非Web项目打Jar包是有自己的方法的,下面这篇文章主要给大家介绍了关于IDEA+Maven打JAR包的两种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • Jackson java动态去除返回json中的值方式

    Jackson java动态去除返回json中的值方式

    文章介绍了在Java中使用@JsonInclude注解动态去除返回JSON中的非必需字段(如分页信息)的解决方案,通过在字段上添加@JsonInclude注解并选择合适的策略(如NON_NULL或NON_EMPTY),可以在非分页情况下取消分页字段,从而提高返回结果的灵活性和效率
    2024-12-12
  • 基于Java SWFTools实现把pdf转成swf

    基于Java SWFTools实现把pdf转成swf

    这篇文章主要介绍了基于Java SWFTools实现把pdf转成swf,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Java集合ArrayDeque类实例分析

    Java集合ArrayDeque类实例分析

    这篇文章主要介绍了Java集合ArrayDeque类实例分析的相关资料,需要的朋友可以参考下
    2017-04-04

最新评论