AtomicInteger原理和CAS与Synchronized(juc编程)

AtomicInteger原理

4.6.1 原理介绍

AtomicInteger的本质:自旋锁 + CAS算法

CAS的全成是: Compare And Swap(比较再交换); 是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令。CAS可以将read-modify-write转换为原子操作,这个原子操作

直接由处理器保证。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当旧预期值A和内存值V相同时,将内存值V修改为B并返回true,否则什么都不做,并返回false。

举例说明:

  1. 在内存值V当中,存储着值为10的变量。
    在这里插入图片描述

  2. 此时线程1想要把变量的值增加1。对线程1来说,旧的预期值 A = 10 ,要修改的新值 B = 11。

在这里插入图片描述

  1. 在线程1要提交更新之前,另一个线程2抢先一步,把内存值V中的变量值率先更新成了11。
    在这里插入图片描述

  2. 线程1开始提交更新,首先进行A和内存值V的实际值比较(Compare),发现A不等于V的值,提交失败。
    在这里插入图片描述

  3. 线程1重新获取内存值V作为当前A的值,并重新计算想要修改的新值。此时对线程1来说,A = 11,B = 12。这个重新尝试的过程被称为自旋
    在这里插入图片描述

  4. 这一次比较幸运,没有其他线程改变V的值。线程1进行Compare,发现A和V的值是相等的。
    在这里插入图片描述

  5. 线程1进行SWAP,把内存V的值替换为B,也就是12。

在这里插入图片描述

举例说明:这好比春节的时候抢火车票,下手快的会抢先买到票,而下手慢的可以再次尝试,直到买到票。

4.6.2 源码分析

那么接下来我们就来查看一下AtomicInteger类中incrementAndGet方法的源码。

public class AtomicInteger extends Number implements java.io.Serializable {
    
    // cas算法的实现类
    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
    
    // 表示变量值在内存中的偏移量地址,unsafe类就是根据内存偏移量地址获取数据值。
    private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
    private volatile int value;
    
    // 以原子方式将当前值加1,这里返回的是自增后的值
    public final int incrementAndGet() {
        
        /* this表示当前AtomicInteger对象 ,1表示要增加的值 */
        return U.getAndAddInt(this, VALUE, 1) + 1;		// 调用Unsafe类中的getAndAddInt方法
        
    }
    
}

UnSafe类

public final class Unsafe {
    
    // Unsafe类中的getAndAddInt方法
    public final int getAndAddInt(Object o, long offset, int delta) {
        
        int v;
        
        // do...while就是自旋操作,当CAS成功以后,循环结束
        do {
            // 获取AtomicInteger类中所封装的int类型的值,就相当于旧的预期值A
            v = getIntVolatile(o, offset); 
            
            // 调用本类的weakCompareAndSetInt方法实现比较在交换; o: AtomicInteger对象, v: 相当于旧的预期值A, v + delta:新值B
        } while (!weakCompareAndSetInt(o, offset, v, v + delta));
        
        return v;
    }
    
    // Unsafe类中的weakCompareAndSetInt方法
    public final boolean weakCompareAndSetInt(Object o, long offset, int expected, int x) {
        return compareAndSetInt(o, offset, expected, x);
    }

    // 本地方法,调用CPU指令实现CAS
    public final native boolean compareAndSetInt(Object o, long offset, int expected, int x);
    
}

4.7 CAS与Synchronized

CAS和Synchronized都可以保证多线程环境下共享数据的安全性。那么他们两者有什么区别?

Synchronized是从悲观的角度出发:

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线

程阻塞,用完后再把资源转让给其它线程)。因此Synchronized我们也将其称之为悲观锁。jdk中的ReentrantLock也是一种悲观锁。

CAS是从乐观的角度出发:

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。CAS这种机制我们也可以将其称之为乐观锁。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue小总结

知识总结 【 1 】es6 语法总结 # let 定义变量 # const定义常量 ------块级作用域---- # var 以后尽量少用,函数作用域var 在 JavaScript 中是函数作用域或全局作用域。而 let 和 const 是块级作用域。 // 使用 var 声明全局变量 var globalVar "Im a globa…

【机器学习】从理论到实践:决策树算法在机器学习中的应用与实现

📝个人主页:哈__ 期待您的关注 目录 📕引言 ⛓决策树的基本原理 1. 决策树的结构 2. 信息增益 熵的计算公式 信息增益的计算公式 3. 基尼指数 4. 决策树的构建 🤖决策树的代码实现 1. 数据准备 2. 决策树模型训练 3.…

DAB-DETR

论文地址: https://arxiv.org/pdf/2201.12329 文章通过前人的经验得出,导致 DETR 训练速度慢的原因很大可能是因为 decoder 中 cross attention 这个模块,由上面的对比可以看出其与 self attention 的区别主要就在于query的不同。文章猜想两个…

Java 8 Stream API介绍

Java 8引入了Stream API,这是对集合框架的一种增强,它允许你以一种声明式的方式处理数据集合。Stream API的核心在于将数据的操作分为两个主要阶段:中间操作和终端操作。中间操作返回的是一个新的Stream,可以链式调用多个中间操作…

C语言 图的基础知识

图 图的基本概念图的存储方法**邻接矩阵**:邻接表 图的遍历深度优先(DFS)广度优先(BFS) 最小生成树Prim算法Kruskal算法 最短路径问题 图的基本概念 图的定义: 图是由顶点的非空有穷集合与顶点之间关系&am…

opencv的RGB 颜色表

RGB(255,23,140)是光的三原色,也即是红绿蓝Red,Green,Blue,它们的最大值是255,相当于100%。 白色:rgb(255,255,255) 黑色:rgb(0,0,0) 红色:rgb(255,0,0) …

我的创作纪念日--码农阿豪

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

分支结构相关

1.if 语句 结构: if 条件语句: 代码块 小练习: 使用random.randint()函数随机生成一个1~100之间的整数,判断是否是偶数 import random n random.randint(1,100) print(n) if n % 2 0:print(str(n) "是偶数") 2.else语…

模拟原神圣遗物系统-小森设计项目,设计圣遗物(生之花,死之羽,时之沙,空之杯,理之冠)抽象类

分析圣遗物 在圣遗物系统,玩家操控的是圣遗物的部分 因此我们应该 物以类聚 人与群分把每个圣遗物的部分,抽象出来 拿 生之花,死之羽为例 若是抽象 类很好的扩展 添加冒险家的生之花 时候继承生之花 并且名称冒险者- 生之花 当然圣遗物包含…

返回给前端数据的封装

返回格式如下: { "code": 200/400, "msg": "成功"/"失败", "total": n, "data": [ {},{}]} 1.在common中新增Result 类,代码如下 package com.xxx0523.common; import lombo…

【全网最全最详细】RabbitMQ面试题

一、说下RabbitMQ的架构大致是什么样的? RabbitMQ是一个开源的消息中间件,用于在应用程序之间传递消息。它实现了AMQP(高级消息队列协议)并支持其它消息传递协议,例如STOMP(简单文本定向消息协议&#xff…

【机器学习】机器学习重要方法—— 半监督学习:理论、算法与实践

文章目录 引言第一章 半监督学习的基本概念1.1 什么是半监督学习1.2 半监督学习的优势 第二章 半监督学习的核心算法2.1 自训练(Self-Training)2.2 协同训练(Co-Training)2.3 图半监督学习(Graph-Based Semi-Supervise…

蓝鹏测控公司全长直线度算法项目多部门现场组织验收

关键字:全场直线度算法,直线度测量仪,直线度检测,直线度测量设备, 6月18日上午,蓝鹏测控公司全长直线度算法项目顺利通过多部门现场验收。该项目由公司技术部、开发部、生产部等多个部门共同参与,旨在提高直线度测量精度,满足高精度制造领域需…

[SAP ABAP] 数据类型

1.基本数据类型 示例1 默认定义的基本数据类型是CHAR数据类型 输出结果: 示例2 STRING数据类型用于存储任何长度可变的字符串 输出结果: 示例3 DATE数据类型用于存储日期信息,并且可以存储8位数字 输出结果 提示Tips:日期和时间类型的变量可以直接进…

【数学建模】——【新手小白到国奖选手】——【学习路线】

专栏:数学建模学习笔记 目录 ​编辑 第一阶段:基础知识和工具 1.Python基础 1.学习内容 1.基本语法 2.函数和模块 3.面向对象编程 4.文件操作 2.推荐资源 书籍: 在线课程: 在线教程: 2.数学基础 1.学习内…

视频智能分析平台LntonAIServer安防监控视频平台行人入侵检测算法核心特点及其应用价值

LntonAIServer行人入侵检测算法是一种基于深度学习和计算机视觉技术的先进解决方案,旨在提高监控系统的智能化水平,有效预防未经授权的人员进入重要场所,保障安全生产和管理。以下是关于该算法的主要特点和应用的详细介绍: 核心特…

海外小米上架规则

一、应用创建 第1步:打开小米国际应用商店开发者站 ,点击【分发】,登陆/注册开发者 1.1点击开发者站,点击【分发】 小米国际应用商店开发者站 地址:Mi Developer 1.2使用注册邮箱/手机号码/小米ID登录开发者账号 使…

【Python日志模块全面指南】:记录每一行代码的呼吸,掌握应用程序的脉搏

文章目录 🚀一、了解日志🌈二、日志作用🌈三、了解日志模块⭐四、日志级别💥五、记录日志-基础❤️六、记录日志-处理器handler🎬七、记录日志-格式化记录☔八、记录日志-配置logger👊九、流程梳理 &#x…

AWR1843BOOST上的TM4C1294NCPDT是干啥用的?

摘要:AWR1843BOOST上面有2个体积较大的芯片,一片是雷达,另一片是什么呢? 答案:它就是XDS110仿真器。 有了它,就不用再买一个仿真器了。 从AWR1843BOOST的原理图中可以看到整个 BOOST板子上只有2个比较大的…

java环境变量配置以及“‘javac‘ 不是内部或外部命令”问题的解决方法(2024年6月姆级最新)

😀前言 有很多小伙伴提问这个所以就单独出一个解决教程 java环境变量配置以及“‘javac’ 不是内部或外部命令”问题的解决方法(2024年6月姆级最新) 安装的话可以参考这个 java 安装和环境配置(2024-4月保姆级最新版) 🏠个人主页…