Java i++操作不是原子性的,怎么理解?

Java中的i++操作分为三步:

  1. 将i压入栈顶
  2. 将1压入栈顶
  3. 将+号压入栈顶,发现是运算符,弹出i和1,进行加法运算,再返回栈顶。

通过Java的字节码指令来验证

编写下面这段java程序:

class Main{int i; public static void main(String[] args){new Main().increas();}public void increas(){i++;}
}

运行javac命令,进行编译:

javac Main.java

得到Main.class字节码文件,此时如果直接打开class文件,是一串二进制数据,无法阅读,可以通过javap命令反编译class文件:

javap Main.class

得到以下输出:

Compiled from "Main.java"
class Main {int i;Main();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic static void main(java.lang.String[]);Code:0: new           #2                  // class Main3: dup4: invokespecial #3                  // Method "<init>":()V7: invokevirtual #4                  // Method increas:()V10: returnpublic void increas();Code:0: aload_01: dup2: getfield      #5                  // Field i:I5: iconst_16: iadd7: putfield      #5                  // Field i:I10: return
}

我们主要看increas方法部分:

  public void increas();Code:0: aload_01: dup2: getfield      #5                  // Field i:I5: iconst_16: iadd7: putfield      #5                  // Field i:I

以下是对应字节码指令的解释:

在Java中,每个操作都对应一个或多个字节码指令。这些指令是Java虚拟机(JVM)执行的最低层次的命令。

  1. aload_0:

    • 这条指令用于将局部变量数组中的第一个元素(在这种情况下是this引用,指向当前的Main对象)加载到操作栈上。在非静态方法中,局部变量的第0位总是用于存储对当前对象的引用。
  2. dup:

    • dup是一个复制指令,它复制操作栈顶的值并将复制值压回栈顶。这里它用来复制this引用,因此操作栈上会连续有两份this引用。
  3. getfield #5:

    • getfield指令用于获取对象的实例字段。这里它使用#5作为索引,这通常指向常量池中的一个字段描述,表示Main类中的i字段(类型为int)。指令执行后,它会将this.i的值加载到栈顶,替换掉之前的一个this引用。
  4. iconst_1:

    • 这条指令将整数1压入操作栈顶。这用于后续的增加操作。
  5. iadd:

    • iadd是一个整数加法指令,它从栈顶弹出两个整数值,将它们相加,然后将结果压回栈顶。在这里,它将栈顶的1(通过iconst_1加载)和Main.i的当前值(通过getfield加载)相加。
  6. putfield #5:

    • putfield指令用于将栈顶的值(这里是i + 1的结果)赋值给对象的实例字段。与getfield一样,#5指代Main类中的i字段。在这里,它首先弹出栈顶的增加后的值(i+1),然后弹出下一个栈顶的this引用,最终将增加后的值赋给这个引用指向的对象的i字段。

通过上述指令,increas方法实现了i字段的自增操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2998753.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基于ESP32—CAM物联网WIFI小车

一.功能概述 摄像头的画面可以实时的传输到&#xff0c;点灯科技APP的手机端&#xff0c;这样可以实时查看周围环境的状况&#xff0c;灯光不足&#xff0c;画面不清晰时可以打开灯光照明。手机端有左转、右转、前进、后退、停止的按钮。可以根据自己需要&#xff0c;来控制小车…

南京航空航天大学用契约锁让校园业务盖章“腾出手”、办事更便捷

南京航空航天大学&#xff08;以下简称“南航”&#xff09;创建于1952年&#xff0c;是国家“双一流”建设高校&#xff0c;国家“211工程”、“985工程优势学科创新平台”重点建设高校之一&#xff0c;同时也是新中国自己创办的第一批航空高等院校之一。 创新高校网上签字盖…

Vitis HLS 学习笔记--Schedule Viewer 调度查看器

目录 1. 简介 2. Schedule Viewer详解 2.1 视图说明 2.1.1 Operation\Control Step 2.1.2 周期关系图 2.1.3 Schedule Viewer 菜单栏 2.1.4 属性视图 2.2 内容说明 2.2.1 实参&#xff08;b&#xff09;解释 2.2.2 实参&#xff08;a&#xff09;解释 2.2.3 变量&am…

一、初识Django

简介 Django 是一个用于构建 Web 应用程序的高级 Python Web 框架。 版本对应 不同版本的django框架是基于特定的不同的python版本开发的&#xff0c;所以不同版本的django框架要正常执行功能只能安装特定的python版本 Django安装 安装 Django # 全局安装 pip install dj…

第一个Cython程序-helloworld

Cython是Python的一个模块&#xff0c;可以将python语言“翻译”成C语言。 如何安装&#xff1f; python -m pip install Cython -i https://pypi.tuna.tsinghua.edu.cn/simple/ 新建两个文件helloworld.pyx和setup.py。 helloworld.pyx print("hello world")setu…

MySQL中SELECT语句的执行过程

2.1.1. 一条SELECT语句的执行过程 MySQL 的架构共分为两层&#xff1a;Server 层和存储引擎层 Server层负责建立连接、分析和执行SQL存储引擎层负责数据的存储和提取&#xff0c;支持 InnoDB、MyISAM、Memory 等多个存储引擎&#xff0c;MySQL5.5以后默认使用InnoDB&#xff0…

一个单例模式中使用std::unique_ptr引起的莫名其妙的COFF损坏的问题(未解决)

使用static std::unique_ptr和static std::shared_ptr都不行struct IElementAgendaEvents {//! Called to allow listeners to modify the agenda by adding/removing entries before applying tool operation. Return true if entries added or invalidated.virtual bool …

【触摸案例-事件的产生和传递 Objective-C语言】

一、事件的产生和传递 1.事件的产生和传递 1)涉及到的两个方法 2)响应者链条 这个东西呢,比较绕,然后我们接下来一块儿来看一下啊, 我们把上午最后的一份代码,复制粘贴一下,改个名字,叫做“05-事件的产生和传递”, 首先,我们上午说了一下,这个hit test这个方法,…

算法设计与分析 3.2 牛顿法及改进、迭代法、矩阵谱半径、雅可比迭代、高斯迭代

思考题1 改进cosx&#xff1f;优化算法 关键点在于cos计算过于麻烦&#xff0c;而每次都要求sinx的值 故直接简化为cosx的导数 -sinx 即&#xff1a; 原&#xff1a;//double daoshu(double x) { // return 18 * x - cos(x); //} 改&#xff1a;double daoshu(double x) {retu…

Git中单独的功能特性分支是什么含义

在Git中&#xff0c;一个"功能特性分支"&#xff08;通常简称为“特性分支”&#xff09;是指从主开发分支&#xff08;比如main或master&#xff09;独立出来的分支&#xff0c;专门用于开发一个新功能、修复一个bug&#xff0c;或者进行实验性的尝试。使用特性分支…

LT9611单/双端口 MIPI CSI/DSI 转 HDMI 1.4 发射器,龙迅方案

1. 描述LT9611 MIPI DSI/CSI 至 HDMI1.4 桥接器具有双端口 MIPI D-PHY 接收器前端配置&#xff0c;每个端口有 4 个数据通道&#xff0c;每个数据通道以 2Gbps 的速度工作&#xff0c;最大输入带宽为 16Gbps。该桥接器提供一个 HDMI 数据输出&#xff0c;具有可选的 SPDIF 或 8…

【CGALDotNet】CGAL的C#封装(C#调用编译好的CGAL的dll)

介绍 开源项目出处&#xff08;两个模块&#xff09;&#xff1a; 链接1&#xff1a;https://github.com/Scrawk/CGALDotNet/tree/master?tabreadme-ov-file 链接2&#xff1a;https://github.com/Scrawk/CGALDotNetGeometry 该项目提供了编译的、封装相关接口后的CGAL库&am…

Java将文件目录转成树结构

在实际开发中经常会遇到返回树形结构的场景&#xff0c;特别是在处理文件系统或者是文件管理系统中。下面就介绍一下怎么将文件路径转成需要的树形结构。 在Java中&#xff0c;将List<String>转换成树状结构&#xff0c;需要定义一个树节点类&#xff08;TreeNode&#…

【前端】表格合并如何实现?

简言 介绍实现表格合并的一种方法。 表格合并 表格合并操作是一个比较复杂的操作&#xff0c;它主要分为以下步骤&#xff1a; 获取选中区域选择合并显示的单元格实现合并操作。 我们就逐一实现这三步&#xff0c;最后实现一个较完整的合并操作。&#xff08;不考虑边界情…

《ElementPlus 与 ElementUI 差异集合》el-dialog 显示属性有差异

ElementPlus 用属性 v-model ElementUI 用属性 visible 其实也是 Vue2/Vue3 的差异&#xff1a;v-model 指令在组件上的使用已经被重新设计&#xff0c;替换掉了 v-bind.sync

【酱浦菌-爬虫项目】爬取学术堂论文信息

1. 首先&#xff0c;代码定义了一个名为 url 的变量&#xff0c;它是一个包含三个网址的集合&#xff08;或者说是一个集合的字典&#xff09;。这些网址分别是&#xff1a; - ‘http://www.xueshut.com/lwtimu/127966.html’ - ‘http://www.xueshut.com/lwtimu/12…

【百度Apollo】探索自动驾驶:Apollo 新版本 Beta 全新的Dreamview+,便捷灵活更丰富

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引入一、Dreamview介绍二、Dreamview 新特性2.1、基于模式的多场景——流程更简洁地图视角调节&#xff1a;调试流…

【AIGC调研系列】LLaVA++整合Phi-3和Llama-3能够实现什么

LLaVA能够为Phi-3和Llama-3带来的主要好处包括&#xff1a; 视觉处理能力的增强&#xff1a;通过整合Phi-3和Llama-3模型&#xff0c;创建了具备视觉处理能力的Phi-3-V和Llama-3-V版本&#xff0c;这意味着这些模型现在能够理解和生成与图像相关的内容[1]。这种能力的增加&…

天冕科技亮相第十七届深圳国际金融博览会!

第十七届深圳国际金融博览会在深圳会展中心正式开幕&#xff0c;天冕科技跟随南山区组团集体亮相&#xff0c;充分展现金融活力。此次金博会&#xff0c;南山区政府共遴选了包括天冕科技在内的三家优秀金融科技企业组团参展&#xff0c;以特色与创新的案例展示了辖区金融业发展…

Eclipse:-Dmaven.multiModuleProjectDirectory system propery is not set.

eclipse中使用maven插件的时候&#xff0c;运行run as maven build的时候报错 -Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable and mvn script match. 可以设一个环境变量M2_HOME指向你的maven安装目录 M2_HOMED:\Apps\…