Java volatile关键字实现原理
场景引入 可见性问题
先来看一张图:
上面的图,是简化版的Java内存模型,一个线程有自己的工作内存,同时还有一个共享的主内存。
线程1和线程2读取数据data时,先从主内存里加载data变量的值到工作内存,然后才可以使用那个值。
假设现在线程1修改了data变量的值为1,然后将这个修改写入到自己的工作内存。那么此时,线程1的工作内存里data的值为1,而主内存里data的值还是0。线程2的工作内存data值也是0。
这就尴尬了,线程1和线程2操作的是用一个变量data,但由于线程本地缓存的存在,导致线程1对data变量的修改,线程2不能及时看到。
这就是Java并发编程中的可见性问题:当一个线程修改某个共享变量的值,其他线程是否能够立即知道这个修改。
值得注意的是,上面的Java内存模型是极其简化的,真实的情况远比上面复杂。
volatile的作用及实现原理
要解决上述可见性问题,我们可以使用volatile关键字。
在加入volatile关键字后,线程1只要修改data变量的值,就会在修改工作内存data变量值的同时,强制将修改刷新到主内存中。与此同时,线程2需要读取data变量时,先强制将主内存的值刷新到工作内存中,从而保证线程2每次读取都是最新的值。如下图:
volatile工作原理如上所述,其在JVM底层的实现原理,涉及到内存屏障相关概念。简单来说,JVM在在遇到volatile变量时,在其写操作之后插入一个store屏障,在其读操作之前插入一个load屏障。
Java volatile关键字实现原理的更多相关文章
- Java volatile 关键字底层实现原理解析
本文转载自Java volatile 关键字底层实现原理解析 导语 在Java多线程并发编程中,volatile关键词扮演着重要角色,它是轻量级的synchronized,在多处理器开发中保证了共享变 ...
- [Java并发编程(五)] Java volatile 的实现原理
[Java并发编程(五)] Java volatile 的实现原理 简介 在多线程并发编程中 synchronized 和 volatile 都扮演着重要的角色,volatile 是轻量级的 sync ...
- [Java并发编程(三)] Java volatile 关键字介绍
[Java并发编程(三)] Java volatile 关键字介绍 摘要 Java volatile 关键字是用来标记 Java 变量,并表示变量 "存储于主内存中" .更准确的说 ...
- 13、Java并发性和多线程-Java Volatile关键字
以下内容转自http://tutorials.jenkov.com/java-concurrency/volatile.html(使用谷歌翻译): Java volatile关键字用于将Java变量标 ...
- Java Volatile关键字(转)
出处: Java Volatile关键字 Java的volatile关键字用于标记一个变量“应当存储在主存”.更确切地说,每次读取volatile变量,都应该从主存读取,而不是从CPU缓存读取.每次 ...
- 04 volatile关键字实现原理
volatile关键字实现原理 1.volatile关键字的语义分析 作用:让其他线程能够马上感知到某个线程多某个变量的修改 保证可见性 对共享变量的修改,其他线程能够马上感知到 保证有序性 在重排序 ...
- Java volatile关键字详解
Java volatile关键字详解 volatile是java中的一个关键字,用于修饰变量.被此关键修饰的变量可以禁止对此变量操作的指令进行重排,还有保持内存的可见性. 简言之它的作用就是: 禁止指 ...
- 就是要你懂Java中volatile关键字实现原理
原文地址http://www.cnblogs.com/xrq730/p/7048693.html,转载请注明出处,谢谢 前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是j ...
- 【转】Java学习---Java中volatile关键字实现原理
[原文]https://www.toutiao.com/i6592879392400081412/ 前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.c ...
随机推荐
- 常用的python的内置库或者第三方库
内置库:re,json,time,random,sys,os, 第三方库:转载: https://www.cnblogs.com/jiangchunsheng/p/9275881.htmlReques ...
- SpringBoot2+Druid+MyBatis+MySql实现增删改查
1.配置pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...
- k8s 集群 节点状态显示notready
一般情况下 我们是在maste节点上安装网络插件的,然后在join node 节点,这样导致node节点可能无法加载到这些插件 使用 journalctl -f -u kubelet 显示如下内容 N ...
- pymysql DAO简单封装
#!/usr/bin/env python # -*-coding:utf-8 -*- # # 无法执行多个query,self.conn.close()放在CdbConn类的单独函数中,每次quer ...
- IP address '121.41.35.30' could not be resolved: Name or service not known解决方法
IP address '121.41.35.30' could not be resolved: Name or service not known解决方法 添加如下 然后重启 即可解决<pre ...
- Shell基础快速入门 了解shell运行原理
Shell简介 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了一个界 ...
- mvn: command not found in Jenkins slave
在Jenkins上添加了一个slave node, 并绑定了一个团队项目,通过shell来执行后续操作,结果卡在了 mvn: command not found 其实这个node上是配置了maven的 ...
- springboot 2.1.3.RELEASE添加filter,servlet源码学习
Servlet规范中,通过ServeltContext来注册Filter.Servlet,这里分析Filter,Servlet是相同逻辑 springboot2.0中,我们通过 FilterRegis ...
- docker 容器和镜像常用命令整理
- 【转载】C#使用Math.Sqrt方法进行开平方操作
在C#的数学数值运算中,有时候需要进行对数值进行开平方操作,C#的数值计算类Math类中内置了开平方操作的方法Sqrt,直接调用此方法可计算出相应的平方值,Math.Sqrt方法签名为:double ...