从底层原理深度剖析volatile关键字

erichi101 erichi101     2022-11-28     202

关键词:

 

本篇文章从底层原理层面深度剖析volatile关键字是如何实现内存可见性的,同时引入了Java内存模型、指令重排序以及内存屏障等知识点作为原理分析的知识支撑。

阅读本文之前,推荐大家先阅读作者之前的一篇关于happens-before的文章,这样更有助于大家对volatile关键字底层原理的理解。

面试官为什么总是问happens-before规则,看完这篇文章你就懂了

简述Java内存模型

Java内存模型分为主内存和线程工作内存两大类。

主内存:多个线程共享的内存。如下图所示,方法区和堆属于主内存区域。

线程工作内存:每个线程独享的内存。如下图所示,虚拟机栈、本地方法栈、程序计数器属于线程独享的工作内存。

 

技术图片

 

 

 

Java内存模型规定:所有变量都需要存储在主内存中,线程工作内存保存了变量在主内存中的副本,线程对变量的所有操作都在工作内存中进行,执行结束后在同步到主内存中去。这里必然会存在时间差,在这个时间差内,该线程对副本的操作,对于其他线程是不见的,从而造成了可见性问题。

技术图片

 

 

指令重排序

JVM对代码进行编译优化,导致代码可能并不是按照代码编写顺序执行,而是按照JVM进行编译优化后的顺序执行。指令重排序对并发编程安全性有很大影响,所以提供了一些happens-before规则定义一些禁止编译优化的场景。

volatile的作用

保证共享变量的可见性:使用volatile修饰的变量,任何线程对其进行操作都是在主内存中进行的,不会产生副本,从而保证共享变量的可见性。

防止局部指令重排序:happens-before规则中的volatile变量规则规定了一个线程先去写一个volatile变量,然后一个线程去读这个变量,那么这个写操作的结果一定对读的这个线程可见。

 

volatile如何防止指令重排序

volatile是通过内存屏障来防止指令重排序的。

硬件层面的内存屏障分为Load Barrier 和 Store Barrier即读屏障和写屏障。

对于Load Barrier来说,在指令前插入Load Barrier,可以让高速缓存中的数据失效,强制从新从主内存加载数据。对于Store Barrier来说,在指令后插入Store Barrier,能让写入缓存中的最新数据更新写入主内存,让其他线程可见。Java内存屏障类型把上述两种内存屏障两两组合,如下图所示:

技术图片

 

 

volatile防止指令重排序具体步骤:

1.在每个volatile写操作的前面插入一个StoreStore屏障。

2.在每个volatile写操作的后面插入一个StoreLoad屏障。

3.在每个volatile读操作的后面插入一个LoadLoad屏障。

4.在每个volatile读操作的后面插入一个LoadStore屏障。

 

技术图片

 

volatile写内存屏障示意图 

技术图片

 

 volatile读内存屏障示意图

 

volatile总结

volatile解决的是多线程共享变量可见性问题,但是被volatile修饰的变量操作并非具有原子性。如下面代码所示:

技术图片

 

 

上述代码两个线程同时执行count++操作1000次,多次执行结果均不为2000,可见被volatile修饰的变量操作不具有原子性。注:可以通过对count++加锁的方式或使用AtomicLong和LongAdder(JDK8推荐使用)类来实现count++的原子性。

 

zz:https://baijiahao.baidu.com/s?id=1655055831382625926&wfr=spider&for=pc

玩命死磕java内存模型(jmm)与volatile关键字底层原理(代码片段)

点击上方关注“终端研发部”设为“星标”,和你一起掌握更多数据库知识引言本篇文章结合我个人对Java内存模型的理解以及相关书籍资料为前提全面剖析JMM内存模型,本文的书写思路先阐述JVM内存模型、硬件与OS(... 查看详情

java中volatile关键字,你真的了解吗?volatile原理剖析实例讲解(简单易懂)(代码片段)

i++是否线程安全?在了解volatile之前,我们先思考一个问题,你认为i++是线程安全的吗?为什么呢?,带着这样一个思考,我们进入下文。首先我们来了解一下内存模型。内存模型:Java... 查看详情

java中volatile关键字,你真的了解吗?volatile原理剖析实例讲解(简单易懂)(代码片段)

i++是否线程安全?在了解volatile之前,我们先思考一个问题,你认为i++是线程安全的吗?为什么呢?,带着这样一个思考,我们进入下文。首先我们来了解一下内存模型。内存模型:Java... 查看详情

volatile底层原理详解(代码片段)

volatile关键字是Java虚拟机提供的最轻量级的同步机制。在多线程编程中volatile和synchronized都起着举足轻重的作用,没有这两者,也就没有那么多JUC供我们使用。本文会介绍volatile的作用,着重讲解volatile的底层实现原理... 查看详情

java多线程的volatile底层实现原理

或许你经常被问到?Volatile关键字有何作用?实现这些作用的底层如何实现?Volatile能够保障可见性、有序性?原子性吗?前言我们都知道,Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需... 查看详情

java并发-聊聊volatile

引言谈到volatile关键字,大多数开发者都有一定了解,可以说是开发者非常熟悉,深入之后又非常陌生的一个关键字。相当于轻量的synchronized,也叫轻量级锁,与synchronized相比性能上开销较少,同时又具备了可见性、有序性以及... 查看详情

java多线程的volatile底层实现原理

或许你经常被问到? Volatile关键字有何作用? 实现这些作用的底层如何实现? Volatile能够保障可见性、有序性?原子性吗?前言  我们都知道,Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,J... 查看详情

atomic包底层实现原理

一、概念介绍(一)volatile关键字Java因为指令重排序,优化我们的代码,让程序运行更快,也随之带来了多线程下,指令执行顺序的不可控。1.volatile关键字的作用:内存可见性,修饰的变量发生改变之后对所有线程立即可见禁... 查看详情

javasynchronized实现原理深度剖析(代码片段)

Sync的实现原理sync是jvm的内置锁,底层是通过对象监视器(ObjectMonitor)来实现。而对象监视器的底层实现是通过cas+自旋或者操作系统的互斥量来实现的。通过javap-c命令可以查看到sync方法前后有成对的monitorenter/monitorexit指令... 查看详情

java多线程编程-(11)-从volatile和synchronized的底层实现原理看java虚拟机对锁优化所做的努力

...JVM的实现和CPU的指令。下边我们对常见的实现同步的两个关键字volatile和synchronized进行底层原理的分析,分析之余我们就会了解到JVM在对锁的优化所做的事情,这样的话我们以后在使用这 查看详情

《c语言深度剖析》第一章关键字详解p4c语言从入门到入土(进阶篇)

目录1.return关键字1.1这段代码是能打印出函数里面的内容,但是为什么呢? 1.2为什么会打印出来随机数呢? 1.3然后继续问,计算机中,释放空间是否真的需要将我们的数据全部清为0/1?1.4又一个问题࿰... 查看详情

java中volatile关键字,你真的了解吗?volatile原理剖析实例讲解(简单易懂)(代码片段)

i++是否线程安全?在了解volatile之前,我们先思考一个问题,你认为i++是线程安全的吗?为什么呢?,带着这样一个思考,我们进入下文。首先我们来了解一下内存模型。内存模型:Java... 查看详情

volatile,从jvm的层面解释并发(代码片段)

...子性4.2可见性4.3有序性与指令重排序五、深入剖析volatile关键字5.1volatile关键字的两层语义5.2volatile可以保证可见性5.3volatile不能保证原子性5.4volatile可以保证有序性5.5volatile底层通过lock前缀指令保证可见性和有序性六、使用volatile... 查看详情

volatile,从jvm的层面解释并发(代码片段)

...子性4.2可见性4.3有序性与指令重排序五、深入剖析volatile关键字5.1volatile关键字的两层语义5.2volatile可以保证可见性5.3volatile不能保证原子性5.4volatile可以保证有序性5.5volatile底层通过lock前缀指令保证可见性和有序性六、使用volatile... 查看详情

深度解析volatile关键字(保证够全面)❤❤(代码片段)

深度解析volatile关键字volatile名词解释volatile第一次在c++代码里有接触,当时老师只介绍了其用法,原理这些并没有深入了解,如今再一次在java代码里碰见了。就必须得好好的一探究竟!首先volatile是一个特... 查看详情

深度学习计算机底层原理,深度剖析存储器

系列文章目录1.《带你深挖计算机底层逻辑,打通你计算机基础知识的任督二脉》2.《深度学习计算机底层原理,深度剖析存储器》文章目录系列文章目录前言一、存储器的分类二、多级存储器三、主存储器总结前言   ... 查看详情

362volatile底层原理详解(代码片段)

...码层面2.3、JVM源码层面2.4、汇编层面2.5、硬件层面volatile关键字是Java虚拟机提供的最轻量级的同步机制。在多线程编程中volatile和synchronized都起着举足轻重的作用,没有这两者,也就没有那么多JUC供我们使用。本文会介绍... 查看详情

6volatile原理与使用(代码片段)

摘要:Java的volatile关键字对效率的影响Java关键字用于将一个变量标记为“存储在内存中的变量”。更准确的说,意思就是每一次对volatile标记的变量进行读取的时候,都是直接从电脑的主内存进行的,而不是从cpu的cache中,而且每... 查看详情