Java——》AtomicInteger源码分析

news2025/1/12 4:10:19

推荐链接:
    总结——》【Java】
    总结——》【Mysql】
    总结——》【Redis】
    总结——》【Kafka】
    总结——》【Spring】
    总结——》【SpringBoot】
    总结——》【MyBatis、MyBatis-Plus】

Java——》AtomicInteger源码分析

  • 一、测试用例
  • 二、反编译
  • 三、源码
    • 1、JDK源码
    • 2、调用本地方法的源码和汇编代码
      • (1)本地方法的源码
      • (2)本地的汇编源码
        • 1)linux_x86底层实现
        • 2)windows_x86底层实现

一、测试用例

import java.util.concurrent.atomic.AtomicInteger;

public class CasTest {

    private static volatile int m = 0;

    private static final AtomicInteger x = new AtomicInteger(0);

    public static void increase1() {
        m++;
    }

    public static void increase2() {
        x.incrementAndGet();
    }

    public static void main(String[] args) throws InterruptedException {
        Thread[] t1 = new Thread[20];
        for (int i = 0; i < 20; i++) {
            t1[i] = new Thread(CasTest::increase1);
            t1[i].start();
            t1[i].join(); // join 起了作用
        }

        Thread[] t2 = new Thread[20];
        for (int i = 0; i < 20; i++) {
            t2[i] = new Thread(CasTest::increase2);
            t2[i].start();
            t2[i].join(); // join 起了作用
        }

        System.out.println("int = " + m);
        System.out.println("AtomicInteger = " + x.get());
    }
}

二、反编译

E:\>javap -v "E:\IdeaProjects_mine\demo\target\test-classes\com\example\demo\CasTest.class"

在这里插入图片描述

三、源码

Unsafe 是 CAS 的核心类,Java 无法直接访问底层操作系统,而是通过本地(native)方法来访问。不过尽管如此,JVM 还是开了一个后门:Unsafe 类,它提供了硬件级别的原子操作。

incrementAndGet() -> unsafe 类 -> getAndAddInt 方法 -> compareAndSwapInt 本地方法 -> unsafe.cpp -> atomic_windows_x86.inline.hpp 汇编 -> 最终调用 cmpxchg 指令实现一条语句自增

1、JDK源码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、调用本地方法的源码和汇编代码

在这里插入图片描述

(1)本地方法的源码

路径:\hotspot\src\share\vm\prims\unsafe.cpp

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
  UnsafeWrapper("Unsafe_CompareAndSwapInt");
  oop p = JNIHandles::resolve(obj); //查找要指定的对象
  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); //获取要操作的是对象的字段的内存地址
  return (jint)(Atomic::cmpxchg(x, addr, e)) == e; //执行Atomic类中的cmpxchg
UNSAFE_END

(2)本地的汇编源码

JVM源码对不同操作系统和不同CPU有不同的实现,但都放在\hotspot\src\os_cpu 目录下。

在这里插入图片描述

操作系统文件路径
linux_64x\hotspot\src\os_cpu\linux_x86\vm\atomic_linux_x86.inline.hpp
windows_64x\hotspot\src\os_cpu\windows_x86\vm\atomic_windows_x86.inline.hpp

1)linux_x86底层实现

linux_x86底层实现\hotspot\src\os_cpu\linux_x86\vm\atomic_linux_x86.inline.hpp
inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value) {
  int mp = os::is_MP(); // 内联函数,用来判断当前系统是否为多处理器
  __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
                    : "=a" (exchange_value)
                    : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
                    : "cc", "memory");
  return exchange_value;
}

2)windows_x86底层实现

inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value) {
  // alternative for InterlockedCompareExchange
  int mp = os::is_MP(); // 内联函数,用来判断当前系统是否为多处理器(如果当前系统是多处理器返回1,否则返回0)
  __asm {
    mov edx, dest
    mov ecx, exchange_value
    mov eax, compare_value
    LOCK_IF_MP(mp) // 如果当前系统是多处理器(即mp值为1),则为cmpxchg指令添加lock前缀,否则不加lock前缀
    cmpxchg dword ptr [edx], ecx // cmpxchg是汇编指令,作用是比较并交换操作数

  }
}

Q:为什么要判断当前系统是否为多处理器?
A:这是一种优化手段,认为单处理器的环境没有必要添加lock前缀,只有在多核情况下才会添加lock前缀,因为lock会导致性能下降。

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

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

相关文章

Java基础学习笔记(一)面向对象

序言&#xff1a;主要记录一下java的学习笔记&#xff0c;用作面试复习&#xff0c;参考的学习资料是尚硅谷Java网课链接 面向对象是P39~P69内容 文章目录一、类和对象二、传值方式三、静态与静态代码块四、包五、构造方法六、继承与构造方法七、多态八、方法的重载与重写8.1 …

[JAVA安全]CVE-2022-33980命令执行漏洞分析

前言 在 i春秋的漏洞靶标上看见了此漏洞&#xff0c;所以前来分析一下漏洞原理&#xff0c;比较也是去年 7月的漏洞。 漏洞描述&#xff1a;Apache官方发布安全公告&#xff0c;修复了一个存在于Apache Commons Configuration 组件的远程代码执行漏洞&#xff0c;漏洞编号&am…

Linux驱动

Linux驱动 驱动 1.驱动课程大纲  内核模块  字符设备驱动  中断 2.ARM裸机代码和驱动有什么区别&#xff1f;  共同点&#xff1a;都能够操作硬件 (都操作寄存器)  不同点&#xff1a;  裸机就是用C语言给对应的寄存器里面写值&#xff0c;驱动是按照一定的框架格…

FastReport .NET 2023.1.8 Crack

FastReport .NET适用于 .NET 6、.NET Core、Blazor、ASP.NET、MVC 和 Windows 窗体的全功能报告库。它可以在 Microsoft Visual Studio 2022 和 JetBrains Rider 中使用。 快速报告.NET 利用 .NET 6、.NET Core、Blazor、ASP.NET、MVC、Windows Forms 和 Mono 数据表示领域专家…

前端入门笔记07 —— js应用

DOM基础 document object model 基本操作 增删改查 查&#xff1a; document成员函数传入 id class tagName等内容获取DOM节点css选择去查询节点获取的DOM对象访问DOM对象的成员 let domResult; domResult document.getElementsByTagName(li); //返回一个类数组对象 Node…

Electron对在线网站做数据交互方案,实现在线网站判断Electron调用自定义接口通讯

(防盗镇楼)本文地址:https://blog.csdn.net/cbaili/article/details/128651549 前言 最近在撸VUE,想要实现一份代码既能构建Web又能构建Electron应用 并且能够判断环境是浏览器还是Electron,随后在Electron中做一些特定的事情 以往的Electron通信依靠IPC通信完成,但是发布到…

2023年,“新一代”固定资产管理平台——支持低代码平台

固定资产是各企业和工厂的主要生产要素&#xff0c;占企业整体资金比例较重&#xff0c;而且随着企业的发展&#xff0c;实物资产的数量和员工日益增多&#xff0c;固定资产的重要性日益凸显。如何高效管理这些实物资产也成了企业管理者经常考虑的问题。单纯依靠人工表格管理固…

python(一) 字符串基本用法

python&#xff08;一&#xff09; 字符串基本用法 目录1.环境安装2. 变量介绍3.变量的命名规则4. 字符串 String 基础4.1 title() 修改单词的大小写 title()4.2 upper() : 将字符串全部改为大写4.3 lower(): 将字符串全部改为小写4.4 字符串的拼接 合并字符串5. 使用制表符或者…

关于抖音年前活动的需求与思考

目录 一、前言 二、需求1 1、后端需求 2、前端需求 三、领取抽卡次数需求 1、后端需求 2、前端需求 四、必得现金红包需求 五、送重复卡需求 1、后端需求 2、前端需求 六、幸运抽奖需求 1、抽奖功能 1.1、首次(或多次)3张节气卡 抽奖 1.2、非首次或多次后5张节气…

【阶段三】Python机器学习14篇:机器学习项目实战:支持向量机分类模型

本篇的思维导图: 项目实战(支持向量机分类模型) 项目背景 目前各大新闻网站很多,网站上的消息也是各式各样,本项目通过建立支持向量机分类模型进行新闻文本分类。 数据收集 所需要的数据文件如下百度云盘链接: 链接:https://pan.baidu.com/s/1Zj-uTt_wdRcmDt3aumZ…

Java加解密(七)数字签名

目录数字签名1 定义2 数字签名特点3 应用场景4 JDK支持的信息摘要算法5 Bouncy Castle 支持的信息摘要算法6 算法调用示例数字签名 1 定义 数字签名&#xff08;digital signature&#xff09;是一种电子签名&#xff0c;也可以表示为一种数学算法&#xff0c;通常用于验证消…

【强训】Day06

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、选择二、编程1. 不要二2. 把字符串转换成整数答案1. 选择2. 编程普通小孩也要热爱生活&#xff01; 一、选择 关于抽象类与最终类&#xff0c;下列说法错误的是&#xff1f; A 抽象类能被继承&#xff0c;最终…

C语言零基础项目:六边形扫雷寻宝模式,详细思路+源码分享

程序简介六边形扫雷&#xff0c;寻宝模式&#xff0c;稍稍介绍一下。他也是要把所有安全的地方点出来。他没有扫雷模式的消零算法。每一个安全的点都需要单独挖出来&#xff0c;一次显示一个格子。添加了生命值的概念&#xff0c;也就是说存在一定的容错。显示的数字有别于扫雷…

亚马逊云科技 2022 re:Invent 观察 | 天下武功,唯快不破

引子“天下武功&#xff0c;无坚不摧&#xff0c;唯快不破”&#xff0c;相信大家对星爷电影《功夫》中的这句话耳熟能详。实际上&#xff0c;“天下武功&#xff0c;唯快不破”最早出自古龙先生的著名武侠小说《小李飞刀》&#xff1a;“小李飞刀&#xff0c;例无虚发&#xf…

LeetCode(String) 2325. Decode the Message

1.问题 You are given the strings key and message, which represent a cipher key and a secret message, respectively. The steps to decode message are as follows: Use the first appearance of all 26 lowercase English letters in key as the order of the substit…

React生命周期详解

React 类组件生命周期 React 有两个重要阶段 render 阶段和 commit 阶段&#xff0c;React 在调和( render )阶段会深度遍历 React fiber 树&#xff0c;目的就是发现不同( diff )&#xff0c;不同的地方就是接下来需要更新的地方&#xff0c;对于变化的组件&#xff0c;就会执…

Linux杂谈之java命令

一 java &#xff08;1&#xff09;基本解读 ① JAVA8 官方命令行参数 linux版的java 重点关注&#xff1a; java、javac、jar、keytool 这三个参数学习方式&#xff1a; 通过man java和官方文档快速学习 如何在官网搜索 java的命令行参数用法 ② 语法格式 ③ 描述 1)…

Java开发为何深入人心 ?我来带你解开 Spring、IoC、DI 的秘密~

目录 一、什么是Spring? 1.1、什么是容器&#xff1f; 1.2、IoC是什么&#xff1f; 1.3、IoC带来了什么好处&#xff1f; 二、什么是DI&#xff1f; 2.1、IoC和DI有什么关系&#xff1f; 一、什么是Spring? 一句概括&#xff0c;Spring 是包含了众多⼯具⽅法的 IoC 容器…

RHCE第七天之防火墙详解

文章目录一、 基本概念二、iptables三、firewalld四、实验练习一、 基本概念 什么是防火墙&#xff1f;路由策略和策略路由/ipsec vpn gre hdlc ppp 硬件 iDS 在计算中&#xff0c;防火墙是基于预定安全规则来监视和控制传入和传出网络流量的网络安全系统。该计算机流入流出的…

React基础梳理,万字总结,总能帮到你~

第1章&#xff1a;React入门 1.1.React简介 1.英文官网: reactjs.org/2.中文官网: react.docschina.org/3.用于动态构建用户界面的 JavaScript 库(只关注于视图)4.Facebook开源 React的特点 1.声明式编码2.组件化编码3.React Native 编写原生应用4.高效&#xff08;优秀的D…