Java volatile关键字详解

STM32通过ESP8266连接机智云APP(第二讲,烧录固件并测试) 今天与大家分享STM32通过ESP8266连接机智云APP,并完成数据的上传下发第二讲。带大家一起烧录机智云固件到ESP8266并且将其通过机智云串口助手与APP进行测试。 阅读详情

前言:
关于volatile详解,已经烂大街,今年是工作第三年,可我尽然无法清晰地跟别人解释清什么是volatile关键字,为什么要有volatile关键字,以及关键字的原理是什么?如果您看到这里,我也希望您回想一下,能否回答这三个问题,如果不能请继续往下看!
本文从以下三方面进行讲解:

  • 为什么需要volatile关键字以及volatile关键字是什么(原理)
  • volatile应用场景
  • volatile性能怎么样

1、为什么需要volatile关键字

1.1 物理机内存模型

众所周知,由于计算机存储设备与处理器的运算速度有几个数量级差距,现代计算机都不得不加一层读写尽可能接近处理器运算速度的高速缓存(Cache)作为内存与cpu之间的缓存,将运算需要的数据复制到缓存,让运算快速进行;当运算结束后再从缓存同步会内存,这样处理器就无需等待缓慢的内存读写了。但这引起了新的问题:缓存一致性(Cache Coherence)。即多处理器系统,每个处理器都有自己的高速缓存,但又共享同一主内存(Mian Memory),当运算都涉及同一块主内存,那么将谁的数据同步到主内存,以谁的为准呢?为解决一致性问题,物理机处理器都遵循一些协议来解决一致性。
除了高速缓存,为了是处理器内部运算单元尽可能被充分利用,处理器可能对输入的代码乱序执行(Out-Of-Order Execution)优化。与处理器乱序执行优化类似,JVM即时编译也有类似的指令重排序(Instruction Reorder),内存模型如下图:
在这里插入图片描述

1.2 Java内存模型

接下来我们看Java内存模型,先上图,其实和物理机内存模型类似
在这里插入图片描述

看到这里,各位筒子们可以想一下我们的问题,为什么需要volatile关键字(想一下再看下面内存哦)?
简单来说:引入volatile关键字是为了保证主内存的变量对于不同线程是立即可见的,这样解决了可见性问题,但无法解决高并发。下面说一下volatile是什么?

2. volatile是什么?

关键字volatile是JVM提供的最轻量级的同步机制,当一个变量被定义为volatile时,它将具备两个特性。第一是保证此变量对所有线程的可见性,即一个线程修改变量值,新值对其他线程立即可见(至于原理,本文不进行阐述,有兴趣的童鞋可以翻看周志明老师深入理解JVM第二版P364),而普通变量不能做到这一点。貌似从上面的定义我们可以知道,volatile就能保证多线程再高并发下数据的正确性,因为是立即可见,大家想一下是这样吗?大家可以猜下面一段代码的运行结果:

package com.phil.concurrency.atomicity;

/**
 * 功能描述:volatile并发测试
 * @auther phil
 * @date: 2019/1/6 20:20
 */
public class AtomicityTest {

    public static volatile int race=1;
    private static final int THREADS_COUNT=20;
     
    public static void increase(){
        race++;
    }
   
    public static void main(String[] args) {
        Thread[] threads = new Thread[THREADS_COUNT];
        for (int i=0;i<THREADS_COUNT;i++){
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j=0;j<10000;j++){
                        increase();
                    }
                }
            });
            threads[i].start();
        }
        //java 1.7线程执行完毕剩下主线程和守护线程,深入理解JVM此处为>1
        while (Thread.activeCount()>2){
            Thread.yield();
        }
        System.out.println(race);
    }
}

这段代码发起了20个线程,每个线程对race变量进行10000次自增操作,如果这段代码能够正确并发的话,最后输出的结果应该是200000。读者运行完这段代码之后,并不会获得期望的结果,而且会发现每次运行程序,输出的结果都不样,都是一个小于200000的数字,这是为什么呢?
问题就再race++,有经经验的程序员都知道race++是非原子性操作,javap反编译可以看到race++有4条字节码构成,从字节码层面上很容易就分析出并发失败的原因了:当getstatic指令把race的值取到操作栈顶时,volatile关键字保证了race的值在此时是正确的,但是在执行iconst_1、iadd这些指令的时候,其他线程可能已经把race的值加大了,而在操作栈顶的值就变成了过期的数据,所以putstatic指令执行后就可能把较小的race值同步回主内存。
在这里插入图片描述
所以volatile并不能保证数据安全.

3. volatile使用场景

由于volatile变量只能保证可见性,在不符合以下两条规则的运算场景中,我们仍然要通过加锁(使用synchronized或java.util.concurrent中的原子类)来保证原子性
①、运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
②、变量不需要与其他的状态变量共同参与不变约束
而在像如下的代码清单12-3所示的这类场景就很适合使用volatile变量来控制并发,当shutdown()方法被调用时,能保证所有线程中执行的doWork()方法都立即停下来

package com.phil.concurrency.atomicity;

/**
 * 功能描述:适合volatile应用场景
 * @auther phil
 * @date: 2019/1/6 20:36
 */
public class Volatile {

    volatile Boolean shutdownRequested;

    public void shurdown(){
        shutdownRequested = true;
    }

    public void doWork(){
        while (!shutdownRequested) {
            //do stuff
        }
    }
}

好,行文至此,向各位看官提问:
1.什么是volatile关键字
2.为了解决什么问题,有什么特性?
如果还不清楚,建议在读一遍文章,或者去周志明老师<<深入理解JVMP>>(第二版)361寻找答案。我们还有volatile禁止重排序特性未讲解,下一篇讲讲解禁止重排序。
欢迎关注我的公众号:
在这里插入图片描述

Ubuntu20.04下 嵌入式 Qt 开发环境的搭建(适用于Tiny6410) Ubuntu 下 Tiny6410 嵌入式 Qt 开发环境的搭建 目录导航Ubuntu 下 Tiny6410 嵌入式 Qt 开发环境的搭建前言1.安装前的准备工作2.安装交叉编译器 前言 这篇文章,主要是基于 Ubuntu19.10版本而写,写此文的初衷,是为了自己使用,因为最近正在以Tiny6410板子做实训,所以也是初学者一枚,只能保证我遇上的问题统统能够解决掉,至于一些没遇上的,欢迎各位看客给我留言,大家一起讨论,一起解决。 注:本文会持续更新 1.安装前的准备工作 环境要求 Linux系统:U 阅读详情

相关推荐

Halcon实战:基于图像清晰度自动筛选最佳对焦图片

本文详细介绍了如何使用Halcon实现基于图像清晰度的自动筛选最佳对焦图片技术。通过分析灰度值统计和标准差等核心指标,结合实战代码示例,帮助开发者高效处理工业检测中的对焦问题,提升自动化检测的准确性和效率。

weixin_27015733的博客 442

JVM内存模型来解释多线程并发常见问题和volilate,final,ThreadLocal

多核CPU运行时,每个CPU都会有自己的Cache,同样jvm运行时,每个线程的私有栈在使用共享数据时,都会现将共享数据拷贝进栈顶进行运算,这份数据其实是副本,因此也同样存在多个线程修改一个内存单元的一致性问题。 JVM有自己的一套内存模型(Java memory model,JMM)。JDK1.2开始有,JDK1.5(JSR-133)才逐渐成熟。JMM中将JVM内存分为“主存”和“工作内存”。

wanglei0622的专栏 2678

4. PCIe 接口时序

在上一篇中,大致介绍IPcore接口。总的来说接口如下图数据的接收和发送通过transmitTLPinterface和ReceiveTLPinterface。收发数据的时序也只是描述这几个接口的关系。从手册上截取PCIex1的接口时序。

jjinl的专栏 6123

在高并发场景下单例模式中volatile关键字的作用

在高并发场景下单例模式中volatile关键字的作用

技术杠精的博客 1090

AWR射频仿真基本操作(一)

这里只讲述一个基本的操作: 软件是AWR 14版本

钢丝 2万+

打包可以在Hadoop 3.3.1和Hive 3.1.2上使用的Tez 0.10.1 minimal

编译打包可以在Hadoop 3.3.1和Hive 3.1.2上使用的Tez 0.10.1

qq_42013533的博客 2618

面试时通过volatile关键字,全面展示线程内存模型的能力

面试时,面试官经常会通过volatile关键字来考核候选人在多线程方面的能力,一旦被问题此类问题,大家可以通过如下的步骤全面这方面的能力。 1首先通过内存模型说明volatile关键字的作用 先说明,用volatile修饰的变量,能直接修改内存内容,修改后的变量对其他线程是可见的。然后展开说明如下的内容。 多线程并发操作同一资源时,可能会出现最终结果和预期不同的情况,刚才我们也已经通过线程安全和不安全相关的案例,直观地看到了这一情况,这里我们将通过线程的内存结构来详细...

hsm_computer的博客 1444

Arduino for ESP32-----ESP-NOW介绍及使用

ESP-NOWESP-NOW介绍ESP-NOW支持以下特性ESP-NOW技术也存在以下局限性获取ESP32的MAC地址ESP-NOW单向通信(One-way communication)ESP32单板间的双向通信一对多通信(一发多收)一对多通信(多发一收) ESP-NOW介绍 ESP-NOW是一种由Espressif开发的协议,可以让多个设备在不使用Wi-Fi的情况下相互通信。该协议类似于低功耗的2.4GHz无线连接。设备之间的配对需要在通信之前完成。配对完成后,连接是安全的、点对点的,不需要握手。这意味着

Better_man1的博客 2万+

日常记录——多线程与高并发—volatile概念、功能、原理、举例、volatile与synchronized的区别

一、概念 volatile是一个特征修饰符(type specifier).volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。 二、功能 1.保证数据可见性 2.禁止指令重排序 注意:不保证原子性 例如:修饰变量的++操作。 三.原理 1.保证数据可见性:依靠MESI(cpu的高速缓存协议),在java内存中,分为主内存和线程内存,主内存中记录变量的值,线程内存在获取变量的值时,先将值copy到自己的内存,执行本线程内操作后,再将变量值写回到主内存。线程之间的

weixin_43001336的博客 284

3D点云-CVPR 2020-PF-Net: Point Fractal Network for 3D Point Cloud Completion

是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像素点与原来像素点比较完成模型的训练。而PF-Net就是采用GAN的思想在3D点云上的应用。

404 Not Found 2369

古风仙侠少女三视图提示词,一键生成角色设定

3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。平视正交视角,统一光照,纯白背景,无文字无水印,避免强透视和动态变形。3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。少女,古风仙侠少女气质,灵动、温婉、仙气。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 1069

JVM简单总结

什么是JVM? JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 JVM的位置 JVM位于操作系统之上。 JVM的体系结构 栈,本地方法栈,程序计数器中没有垃圾回收,因为栈中的方法一用就会弹出去,如果栈中有垃圾,main方法就不会结束,程序就会陷死。所以垃圾回收都在方法区和堆的区域,并且大部分时间在进行堆优化。 类加载器 负责加载class文件,将class文

m0_48847163的博客 247

【Flink】FlinkSQL如何触发执行计算

Table (通过 StatementSet.addInsert() 输出给某个 Sink)和 INSERT 语句 (通过调用 StatementSet.addInsertSql())会先被缓存到 StatementSet 中,StatementSet.execute() 方法被调用时,所有的 sink 会被优化成一张有向无环图。该方法是用来将一个表的内容插入到目标表中,一旦该方法被调用, TABLE API 程序立即被翻译。该方法是用来执行一个 SQL 语句,一旦该方法被调用, SQL 语句立即被翻译。

一杯咖啡半杯糖的博客 1007

java volatile 关键字详解

java volatile 关键字详解 一,什么是volatile关键字,作用是什么 ​ volatile是java虚拟机提供的轻量级同步机制 ​ 作用是: 1.保证可见性 2.禁止指令重排 3.不保证原子性 本篇具体就讲解 什么叫保证了可见性, 什么叫禁止指令重排,什么是原子性 而在这之前需要对JMM 有所了解 二,什么是JMM ​ JMM(java 内存模型 Java Memory Model 简称JMM) 本身是一个抽象的概念,并不在内存中真实存在的,它描述的

clinginh的博客 9724

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java中volatile关键字详解

本文深入解析了Java中volatile关键字的核心机制和实际应用。文章首先介绍了volatile的两大主要特性——保证线程间共享变量的可见性和禁止指令重排序,从而确保多线程环境下数据操作的顺序性。随后,通过具体代码案例展示了volatile在控制线程停止、单例模式中防止指令重排序以及其在复合操作中可能出现的问题

欢迎来到我的技术博客 1620

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java Volatile关键字

Java的volatile关键字用于标记一个变量“应当存储在主存”。更确切地说,每次读取volatile变量,都应该从主存读取,而不是从CPU缓存读取。每次写入一个volatile变量,应该写到主存中,而不是仅仅写到CPU缓存。实际上,从Java 5开始,volatile关键字除了保证volatile变量从主存读写外,还提供了更多的保障。我将在后面的章节中进行说明。

m0_72885838的博客 3403

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Java并发:volatile关键字详解

重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。

2401_84414763的博客 990

java中的Volatile关键字使用

文章目录什么时候使用volatileHappens-Before java中的Volatile关键字使用 在本文中,我们会介绍java中的一个关键字volatile。 volatile的中文意思是易挥发的,不稳定的。那么在java中使用是什么意思呢? 我们知道,在java中,每个线程都会有个自己的内存空间,我们称之为working memory。这个空间会缓存一些变量的信息,从而提升程序的性能。当...

程序那些事 1万+

Java volatile 关键字

同一个成员变量在不同线程中处于各自独立的虚拟机栈帧中,A 线程修改了该变量,B 线程中读的值可能仍然是其内存缓存的值。不管是 cpu 还是虚拟机,都会对操作指令进行重新排序以到达最佳的执行效果,volatile 针对 JVM 指令禁止重排序,达到避免因指令重排在某些边界条件下出现的不符合预期的问题。这是一个典型的双重校验的懒汉式模的单例模式,但这里隐藏着一个重大风险,就是在多线程访问下,在创建之初,某个线程会获取到一个没有执行。在禁止指令重排上的使用场景,接下来再看看确保变量的内存可见性的场景,在。

HJXASLZYY的专栏 771

Java中的volatile关键字详解

volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。 Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此...

刘成 492

Java中Volatile关键字详解

Java中Volatile关键字详解 一、基本概念 先补充一下概念:Java 内存模型中的可见性、原子性和有序性。 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。 可见性,是指线程之间的可见性,一个线程修改的状态对...

蒋蒋 173

java中的volatile 关键字

在 Java 中,volatile是一个类型修饰符(keyword),用于修饰变量。它的主要作用是确保变量的​​和​​,从而在多线程环境下提供一定程度的线程安全保障。volatile关键字提供了一种轻量级的同步机制,适用于某些特定的并发场景,但其功能有限,不能替代诸如等更强大的同步工具。

qq_57019146的博客 1264

Java 关键字 volatile

是 Java 中的一个关键字,用于修饰变量,确保多线程环境下的可见性和有序性。它主要用于解决以下两个问题:在多线程环境中,每个线程都有自己的工作内存(缓存),线程对变量的操作通常是在工作内存中进行的。如果没有同步机制,一个线程对变量的修改可能不会立即反映到主内存中,其他线程也就无法看到最新的值。 问题: 效果:Java 编译器和处理器可能会对指令进行重排序以优化性能,但这可能导致多线程环境下的行为不符合预期。 可以禁止指令重排序,确保代码的执行顺序符合程序员的意图。 问题: 效果: 解决方案:状态标志:

体系化很难,碎片归纳很简单。 1248

Java中Volatile关键字详解及代码示例

转载:https://www.jb51.net/article/128240.htm 这篇文章主要介绍了Java中Volatile关键字详解及代码示例,分为两个部分,第一部分介绍了Volatile关键字的基本概念等内容,第二部分分享了实例代码,具有一定参考价值,需要的朋友可以了解下。 一、基本概念 先补充一下概念:Java内存模型中的可见性、原子性和有序性。 可见性: 可见性是一种...

uflswe的专栏 637

java中volatile关键字的含义_Java里volatile关键字是什么意思

在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉。Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。synchronized同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程...

weixin_42350514的博客 346

Java 中 volatile 关键字的作用是什么?

关键字的理解,包括它的作用、特性(可见性、禁止指令重排)以及局限性(不保证原子性)。回答时需要清晰地解释这些概念,并提供一些代码示例来说明问题。理解这些联系可以帮助你更全面地掌握 Java 并发编程的知识,并了解如何在实际应用中选择合适的同步机制。是 Java 中的一个关键字,用于修饰变量。内存屏障 (Memory Barrier)

qq_63553317的博客 2013
上一篇: 使用easyui发生不关easyui的bug
下一篇: 2018总结,2019计划
道爷野狗
博客等级 码龄11年 9粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值