Java‘volatile conception

手把手教你学Simulink——基于Simulink的PMSM MTPA + FW 全速域平滑切换策略 本文提出一种基于Simulink的PMSM全速域平滑切换控制策略,通过融合MTPA和弱磁控制(FW)实现基速附近的无冲击过渡。在过渡区采用加权融合电流给定方法,使电流超调<5%、转速波动<2%,全速域效率>90%。文章详细介绍了系统架构、核心算法及Simulink建模步骤,包括融合控制器设计、切换逻辑实现和参数优化。仿真结果表明,该方法相比传统硬切换显著改善了动态性能,并扩展了调速范围。同时提供了可直接复用的工程模板和MATLAB代码,为电机控制工程师提供了实用的全速域控制解决方案。 阅读详情

一、Java内存模型

Java内存模型简称JMM (Java Memory Model),是Java虚拟机所定义的一种抽象规范,用来屏蔽不同硬件和操作系统的内存访问差异,让java程序在各种平台下都能达到一致的内存访问效果。

主内存(Main Memory):主内存被所有的线程所共享,对于一个共享变量(比如静态变量,或是堆内存中的实例)来说,主内存当中存储了它的“本尊”。

工作内存(Working Memory):每一个线程拥有自己的工作内存,对于一个共享变量来说,工作内存当中存储了它的“副本”。

工作内存类似高速缓存、Cache,而主存类似于内存,直接操纵主内存速度太慢,所以JVM更倾向于在工作内存操纵线程。线程对共享变量的所有操作都必须在工作内存进行,不能直接读写主内存中的变量。不同线程之间也无法访问彼此的工作内存,变量值的传递只能通过主内存来进行。

JMM工作流程:定义一个静态变量  static int s = 0;线程A执行操作将s修改为3:s = 3;

1)、Thread A先进行读操作,读取主内存 s 值,此时s = 0 ,并更新工作内存s值, s = 0;

2)、在工作内存进行写操作,将s 由 0 写为 3;

3)、同步更新主内存s值,在主内存进行写操作,将s 由 0 改为 3;

通过一系列内存读写的操作指令,线程A把静态变量 s=0 从主内存读到工作内存,再把 s=3 的更新结果同步到主内存当中。从单线程的角度来看,这个过程没有任何问题。此时引入线程B,则结果将会出现两种状态:① Thread B 读出 s = 0, ②Thread B 读出 s = 3。

出现上述结果原因时在,Thread A 进行同步主内存 s = 3 写操作前 ,Thread B 进行主线程的 s 值读取操作,则此时得到结果为s = 0,而当Thread A 进行同步主内存 s = 3 写操作后,Thread B 进行主线程的 s 值读取操作,则此时得到结果为s = 3。

由于 Synchronized 锁会影响程序性能,所以轻量级锁 volatile 出现了。

二、Volatile

volatile关键字其中最重要的特性就是保证了用 volatile 修饰的变量对所有线程的可见性。可见性指当一个线程修改了变量的值,新的值会立刻同步到主内存当中。而其他线程读取这个变量的时候,也会从主内存中拉取最新的变量值。volatile 关键字特性得益于java语言的先行发生原则(happens-before)。

先行发生原则:两个事件的结果之间的关系,如果一个事件发生在另一个事件之前,结果必须反映,即使这些事件实际上是乱序执行的(通常是优化程序流程)。这里的事件指各种指令操作,比如读操作、写操作、初始化操作、锁操作等等。先行发生原则作用于很多场景下,包括同步锁、线程启动、线程终止、volatile。我们这里只列举出volatile相关的规则:对于一个volatile变量的写操作先行发生于后面对这个变量的读操作。

回到上述的代码例子,如果在静态变量s之前加上volatile修饰符:volatile static int s = 0;线程A执行如下代码:s = 3;这时候我们引入线程B,执行如下代码:System.out.println("s=" + s); 当线程A先执行的时候,把 s = 3 写入主内存的事件必定会先于读取s的事件。所以线程B的输出一定是 s = 0。

volatile 只保证变量的可见性,并不能保障变量的原子性,请看一下代码:

package com.demo.sync;

public class VolatileTest {
    public volatile static Integer count = 0;

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e){
                        e.printStackTrace();
                    }

                    //每个线程将count自增100次;
                    for (int j = 0; j < 100; j++) {
                        count++;
                    }
                }
            }).start();
        }
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(count);
    }
}

结果:开启10个线程,每个线程当中让静态变量count自增100次。执行之后会发现,最终count的结果值未必是1000,有可能小于1000,如下图。

分析:count++这一行代码本身并不是原子性操作,在字节码层面可以拆分成如下指令:

getstatic        //读取静态变量(count)

iconst_1        //定义常量1

iadd               //count增加1

putstatic        //把count结果同步到主内存

虽然每一次执行 getstatic 的时候,获取到的都是主内存的最新变量值,但是进行iadd的时候,由于并不是原子性操作,其他线程在这过程中很可能让 count 自增了很多次。这样一来本线程所计算更新的是一个陈旧的count值,自然无法做到线程安全:

 

Volatile适用场景:

1.运行结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。

2.变量不需要与其他的状态变量共同参与不变约束。

volatile static int start = 3;

volatile static int end = 6;

//线程A执行如下代码:

while (start < end){

  //do something

}

//线程B执行如下代码:

start+=3;

end+=3;

这种情况下,一旦在线程A的循环中执行了线程B,start有可能先更新成 6,造成了一瞬间 start == end,从而跳出while循环的可能性。

【心电信号】基于多种滤波去除心电信号基线漂移含Matlab源码 1 简介 心电信号可以用来检测和诊断心脏疾病,心电信号在采集时经常受到呼吸活动、身体运动和皮肤与电极接触不良等影响,因此会产生基线漂移,基线漂移的存在会降低心电信号的质量。所以,在大多数心电信号处理中,包括心律失常的识别、心率变化分析和连续血压测量等,去除基线漂移成为了至关重要的一步。心电信号具有非平稳、非线性的特性,传统的去除心电信号中基线漂移的方法在对心电信号进行去噪时常因去噪过度或者不完全,容易造成大量非线性特征信息的丢失,从而破坏了心电信号本身的动力学特性,这给后续的心电信号信息分析带来了不利影响 阅读详情

相关推荐

高通平台power_supply 框架下添加第三方充电IC的驱动方法

1.power_supply电源框架介绍: power supply framework在kernel/drivers/power/下。内核抽象出来power supply子系统为驱动提供了统一的框架。 功能包括: 1.抽象PSY设备的共性,向用户空间提供统一的API; 2.为底层PSY驱动的编写,提供简单、统一的方式,同时封装并实现公共逻辑。 power supply class位于d...

Change 1万+

漫画:volatile对指令重排的影响

点击上方“程序员小灰”,选择“置顶公众号”有趣有内涵的文章第一时间送达!上一期介绍了volatile关键字对JVM主内存和工作内存的影响,没看过的小伙伴们可以点击下面链接:什么是 volatile 关键字?实在懒得去看也不要紧,我们简单回顾一下:volatile是一个轻量级的线程同步机制。它的特性之一,是保证了变量在线程之间的可见性。当一个线程修改了变量的值,新的值会立刻同步到主内存当中。而其他线

程序员小灰的博客 1800

数字IC物理验证实战 | 从Calibre LVS报告到Innovus定位的Debug全链路解析

本文详细解析了数字IC物理验证中Calibre LVS报告的Debug全流程,从INCORRECT NETS错误的初探到Innovus定位技巧,提供了实战案例和高效工具的使用方法。重点介绍了Calibre高亮功能、Innovus验证命令以及前后端工具联动的关键策略,帮助工程师快速定位和解决LVS问题,提升物理验证效率。

weixin_30919429的博客 127

漫画:什么是 volatile 关键字?

—————  第二天  ————— ———————————— Java内存模型简称JMM(Java

程序员小灰的博客 1948

用Python实现斗地主游戏(终端版)

马上就要过年了 大家也都放假了吧 过年必不可少的活动 打牌! 今天带大家来写一份斗地主 (又是好多天没怎么更新,忙成狗啊) 那么实现一个斗地主呢 我们肯定要先完善卡牌系统 from collections import Counter import numpy as np import itertools def cmp_to_key(mycmp): 'Convert a cmp= function into a key= function' class K: def _

Miku_wx的博客 9855

Python实战:如何用高德API批量获取POI数据(附完整代码)

本文详细介绍了如何使用Python通过高德API批量获取POI数据,包括API基础准备、核心功能模块设计、高级功能实现及实战应用案例。文章提供了完整代码示例,帮助开发者高效解决商业网点分析、公共设施规划等实际项目中的数据采集需求。

stem5的博客 322

volatile详解

 volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。   volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先...

一念永恒 2万+

Modelsim10.5_se安装(Win11)

modelsim是Mentor公司开发的优秀的HDL语言仿真软件。它能提供友好的仿真环境,采用单内核支持VHDL和Verilog混合仿真的仿真器。它采用直接优化的编译技术、Tcl/Tk技术和单一内核仿真技术,编译仿真速度快且编译的代码与平台无关。

m0_51186267的博客 9909

Volatile详解,太详细了-JMM java内存模型

Volatile可能是面试里面必问的一个话题吧,对他的认知很多朋友也仅限于会用阶段,今天我们换个角度去看看。 先来跟着丙丙来看一段demo的代码: 你会发现,永远都不会输出有点东西这一段代码,按道理线程改了flag变量,主线程也能访问到的呀? 为会出现这个情况呢?那我们就需要聊一下另外一个东西了。 JMM(JavaMemoryModel) JMM:Java内存模型,是java虚拟机规范中所定义的一种内存模型,Java内存模型是标准化的,屏蔽掉了底层不同计算机的区别(注意这个跟JVM

没有伞的孩子必须努力奔跑!—小林 1万+

Ollama本地大模型-个性化AI:训练自己的风格模型和数据投喂打造专属智能体验

之前我们使用Ollama下载了deepseek模型,现在我想将其训练成自己风格的模型,应该怎么做?

瑶山的博客 1782

基于R-CNN深度学习的石头剪刀布手势识别系统:数据集、模型和UI界面的完整实现

本项目的目标是开发一个基于R-CNN深度学习模型的手势识别系统,能够识别石头、剪刀、布三种手势,并通过UI界面让用户能够进行交互。数据集准备与标注:收集包含石头剪刀布手势的图像,并对其进行标注。深度学习模型构建与训练:采用R-CNN模型进行手势的识别和定位。UI界面设计:设计一个简洁的界面,用户可以上传手势图像并进行识别。R-CNN(Region Convolutional Neural Networks)是一个典型的目标检测模型。生成候选区域。

YOLO 876

Volatile是什么?

概述Volatile 是 Java 中一个非常有用的关键字,用于保证多线程环境下共享变量的可见性和一致性。可见性在多线程环境中,当一个线程修改了共享变量的值时,其他线程可能无法立即看到最新的值。这是因为每个线程都有自己的工作内存,其中包含对共享变量的副本。当一个线程修改共享变量时,只有该线程的工作内存中的副本才会被更新,而其他线程工作内存中的副本仍然是旧的值。Volatile 可以保证所有线程都能看到共享变量的最新值。当一个线程修改了共享变量的值时,JVM 会将该值刷新到主内存中。

byteinit的专栏 3475

【Unity 实用工具篇】✨| 受击插件Feel 详细教程,开发游戏时更好的操控 游戏打击感

在一个游戏中,游戏手感对于游戏的整体游玩体验是非常重要的,而游戏手感中有一个很重要的点:打击感 那本篇文章就来讲一下打击感中的受击反馈部分。 在游戏中经常会用到攻击敌人,敌人扣血,执行某些受击功能的执行,尤其是对于有战斗场景的游戏来说,这就是标准的受击反馈。 所以引出本篇文章的主角:受击插件 Feel 的使用,2D和3D游戏都可以使用。

努力前行,总会成为自己心中的那道光 3万+

volatile的作用和原理

Volatile关键字的作用主要有如下两个:1. 线程的可见性:当一个线程修改一个共享变量时,另外一个线程能立刻读到这个修改的值。2. 顺序一致性:禁止指令重排序。

乡村非主流2020的博客 5587

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Statistics and Machine Learning Toolbox

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

volatile超详细讲解

目录 写在前面 一、什么是volatile 二、JVM(java虚拟机)、JMM(java内存模型) 三、volatile内存可见性验证 四、可见性说明 五、volitale不保证原子性验证 六、volatile不保证原子性理论解释 七:volatile不保证原子性问题解决 八、volatile指令重排 九、单例模式在多线程环境下可能存在安全问题 写在前面 很多小伙伴相信都会听说过volatile关键字,但是这个关键字有什么作用呢?也许大体也能明白,但是如果碰上较真的面试官,..

秃了也弱了 6702

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

java中的关键字有哪些_java中voliate关键字有什么用?

1、保证内存可见性内存可见性,即线程A对volatile变量的修改,其他线程获取的volatile变量都是最新的。说到内存可见性就必须要提到Java的内存模型,如下图所示:如上图所示,所有线程的共享变量都存储在主内存中,每一个线程都有一个独有的工作内存,每个线程不直接操作在主内存中的变量,而是将主内存上变量的副本放进自己的工作内存中,只操作工作内存中的数据。当修改完毕后,再把修改后的结果放回到主内...

weixin_33245447的博客 825

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C语言中关键字volatile

关键字volatile的理解,作用,使用范围。

m0_67669662的博客 1万+

volatile底层原理详解

JMM中规定所有的变量都存储在主内存(Main Memory)中,每条线程都有自己的工作内存(Work Memory),线程的工作内存中保存了该线程所使用的变量的从主内存中拷贝的副本。线程对于变量的读、写都必须在工作内存中进行,而不能直接读、写主内存中的变量。同时,本线程的工作内存的变量也无法被其他线程直接访问,必须通过主内存完成。整体内存模型如下图所示:对于普通共享变量,线程A将变量修改后,体现在此线程的工作内存。

好好学java 1773

C语言中关键字volatile的含义及用法

上例程序在正常运行的时候确实是好事,但是总会有一些特殊的情况发生,比如,一个中断程序突然改变了valu_1的值为5,那么可能会发生这样的情况:本来valu_1、valu_2和valu_3应该是valu_1改变以后的值5,可是因为编译器在编译时优化valu_1,valu_2,valu_3都是10,因此即使在别的地方被改变成5,但在主函数中使用valu_1、valu_2和valu_3时,其值还是10而不是5,这样程序就会跑出来我们意想不到的结果。,用它声明的类型变量表示可以被某些编译器未知的因素更改。

qq_50654853的博客 5952

详解C/C++中volatile关键字

一、volatile介绍 volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。下面举例说明。在DSP开发中,经常需要等待某个事件的触发,所以经常会写出这样的程序: 这段...

小白的逆袭 8万+

volatile的作用总结与理解

文章目录1. 前言2. `volatile`的作用:2.1 使用`volatile`来解决多核`CPU`高速缓存导致的变量不同步问题;2.2 `volatile` 还可以解决指令重排序问题2.3 `volatile`不能保证操作的原子性 1. 前言 volatile这个关键字比较重要,尤其是在看多线程的时候,会经常出现。那么就来看下这个关键字到底有什么用。 volatile这个关键字的引入是为了线程安全,但是volatile不保证线程安全。 在多处理器的系统中(或者单处理器多核的系统),每个处理器(每个核

梦否 6454

Volatile关键字的作用

Volatile关键字的作用主要有如下两个: 1.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。 2. 顺序一致性:禁止指令重排序。 一、线程可见性 我们先通过一个例子来看看线程的可见性: public class VolatileTest { boolean flag = true; public void updateFlag() { this.flag = false; System.out.println("修改flag

FighterLiu的专栏 7万+

【002 关键字】一文彻底搞懂volatile用法

一、常见说法 volatile 关键字和const对应,一样是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。············ 二、volatile作用 1、 举例说明作用 int i=10; int j =..

kashine的博客 1万+

【Java基础】volatile关键字

关于作者:优快云内容合伙人、技术专家, 从零开始做过日活千万级APP。专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。

fumeidonga的博客 5088

C语言中volatile关键字的作用

文章目录一.前言二.volatile详解: 一.前言 1.编译器优化介绍: 由于内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问。另外在现代CPU中指令的执行并不一定严格按照顺序执行,没有相关性的指令可以乱序执行,以充分利用CPU的指令流水线,提高执行速度。以上是硬件级别的优化。再看软件一级的优化:一种是在编写代码时由程序员优化,另一种是由编译器进行优化。编译器优化常用的方法有:将内存变量缓存到寄存器;调整指令顺序充分利用CPU指令流水线,常见的是重

shouwangyunkai666的博客 7377

volatile关键字的作用

一、volatile关键字的作用 1、保证可见性; 2、防止指令重排; 3、但是不保证原子性; 二、可见性是什么? 在JMM(java memory model)java内存模型中,其他线程从主内存空间把值拷贝到自己的工作空间,线程修改之后的值会返回给主内存,主内存会通知其他线程,此为可见性。 三、指令重排 CPU为了执行效率会并发执行操作指令,volatile可以使指令一个一个的执行。 四、如何解决原子性问题 1、通过synchronized关键字。 2、通过使用AtomicXX,不加锁,采用CAS(co

qq_34287953的博客 1万+
上一篇: Threadpool Description:线程池描述
下一篇: Merge Into 快速更新大量数据
West Money
博客等级 码龄9年 7粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值