当前位置: 首页 > news >正文

Java中原子操作的实现原理

目录

一、处理器如何实现原子操作?

1.使用总线锁保证原子性

1.使用缓存锁保证原子性

二、Java如何实现原子操作?

1)使用循环CAS实现原子操作

2)CAS实现原子操作的三大问题

3)使用锁机制实现原子操作


前言

        原子(atomic)本意是“不能被一步分割的最小粒子,而原子操作(atomic operation)意 为“不可被中断的一个或一系列操作。在多理器上实现原子操作就得有点复们 一起来聊一聊在Intel理器和Java里是如何实现原子操作的。

一、处理器如何实现原子操作?

1.使用总线锁原子性

        第一个机制是通过总线锁 原子性 如果多个 理器同 时对 共享 改写操(i++ 就是 典的 改写操作),那么共享 量就会被多个 理器同 时进 行操作, 这样读 改写操 作就不是原子的,操作完之后共享变 量的 会和期望的不一致。 个例子,如果 i=1 ,我 们进 行 两次i++ 操作,我 期望的 果是 3 ,但是有可能 果是 2 ,如 所示。

1.使用原子性

        第二个机制是通过缓 定来保原子性; 在同一 刻,我 只需保 证对 某个内存地址
的操作是原子性即可,但 总线锁 定把 CPU 和内存之 的通信 住了, 使得 定期 ,其他
理器不能操作其他内存地址的数据,所以 总线锁 定的开 大,目前 理器在某些 合下
使用 定代替 总线锁 定来 化。
但是有两种情况下处理器不会使用缓存锁定:
  • 第一种情况是:当操作的数据不能被缓存在理器内部,或操作的数据跨多个存行 (cache line则处理器会总线锁定。
  • 第二种情况是:有些理器不支持定。Intel 486Pentium理器,就算定的 内存区域在理器的存行中也会总线锁定。

二、Java如何实现原子操作?

1)使用循环CAS实现原子操作

① 什么是CAS

典型的 比较并交换(Compare-And-Swap, CAS)操作,通常用于实现无锁并发编程。CAS 是一种原子操作,用于在多线程环境下确保数据的一致性。

public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
  1. 方法签名public final boolean compareAndSet(int expect, int update):

    • expect:期望的当前值。

    • update:要更新的新值。

    • 返回值:如果操作成功返回 true,否则返回 false

  2. 方法实现:unsafe.compareAndSwapInt(this, valueOffset, expect, update):

    • unsafe: 是一个 Unsafe 类的实例,提供了低级别、不安全的底层由C实现的方法,通常用于直接操作内存。

    • this: 当前对象的引用。

    • valueOffset: 当前对象中某个字段的内存偏移量,用于定位该字段在内存中的位置。

CAS 工作原理

CAS 操作包含三个操作数:内存位置(由 thisvalueOffset 确定)、期望值expect)。新值update)。

CAS 操作的执行过程如下:

  1. 检查内存位置的当前值是否等于期望值(expect)。

  2. 如果相等,则将内存位置的值更新为新值(update),并返回 true

  3. 如果不相等,则不进行任何操作,并返回 false


② 什么是自旋CAS:当一个线程尝试用CAS操作更新某个共享变量时,若操作失败,线程不会进入阻塞;而是循环进行CAS操作直到成功为止;

自旋 CAS 的特点

  1. 无锁:自旋 CAS 不需要使用锁(如 synchronizedReentrantLock),避免了锁带来的开销(如上下文切换、线程阻塞等)。

  2. 乐观并发控制:它前提假设竞争不会频繁发生,因此线程会持续尝试更新,而不是直接进入阻塞状态。

  3. 适用于低竞争场景

    在低竞争情况下,自旋 CAS 的性能优于锁。
    但在高竞争场景下,自旋 CAS 可能导致大量的 CPU 资源浪费(因为线程会不断重试)。
  4. 可能引发 ABA 问题


2)CAS实现原子操作的三大问题

问题一:ABA问题

        CAS在操作值的时候,会检查值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS检查时会发现它的值没有发生变化,但是实际上却变化了。危害如下:

  • 数据不一致:如果程序逻辑依赖于变量的变化历史,ABA 问题可能导致数据不一致。

  • 逻辑错误:ABA 问题可能导致程序逻辑错误。例如,在无锁链表中,节点的指针可能被错误地更新。

        解决思路:就是使用版本号,JDK的Atomic包提供了AtomicStampedReference类来解决ABA问题。该类的compareAndSet方法的作用是首先检查当前引用是否等于预期引用,并且检查前标志是否等于预期标志如果全部相等,才进行更新值。


问题二: 长时间CAS不成功开销大

自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销


问题三:只能保证一个共享变量的原子操作

  • 对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁

  • 或者将多个变量合并,JDK提供了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对象里来进行CAS操作;


3)使用锁机制实现原子操作

        锁机制保证了只有获得锁的线程才能够操作锁定的内存区域。JVM内部实现了很多种锁机制:有偏向锁、轻量级锁和互斥锁。有意思的是除了偏向锁,JVM实现锁的方式都用了循环CAS,即当一个线程想进入同步块的时候使用循环CAS的方式来获取锁,当它退出同步块的时候使用循环CAS释放锁。

相关文章:

Java中原子操作的实现原理

目录 一、处理器如何实现原子操作? 1.使用总线锁保证原子性 1.使用缓存锁保证原子性 二、Java如何实现原子操作? 1)使用循环CAS实现原子操作 2)CAS实现原子操作的三大问题 3)使用锁机制实现原子操作 前言 原子&…...

25农村发展研究生复试面试问题汇总 农村发展专业知识问题很全! 农村发展复试全流程攻略 农村发展考研复试真题汇总

农村发展复试当然有好的建议!前提是复试重点面试题背好! 你是不是也在为农村发展考研复试发愁?担心自己准备不充分、表现不好?别急!今天,学姐——复试面试拿下90分成功上岸的学姐,来给大家分享…...

一维前缀和与二维前缀和

前缀和(Prefix Sum)是一种用于高效计算数组区间和的预处理技术,尤其适用于需要频繁查询子数组或子矩阵和的场景。下面详细讲解一维前缀和与二维前缀和的原理、构建方法及应用。 一、一维前缀和 1. 定义 前缀和数组 prefix 的每个元素 prefi…...

3×2 MIMO系统和2×2 MIMO系统对比

从 SVD(奇异值分解)预编码 的角度分析,32 MIMO 系统相比 22 MIMO 系统在容量、功率分配灵活性和抗干扰能力方面具有潜在优势。以下是具体分析: 1. SVD预编码的基本原理 SVD 预编码是一种基于信道状态信息(CSI&#xf…...

【MySQL — 数据库基础】深入解析 MySQL 的联合查询

1. 插入查询结果 语法 insert into table_name1 select* from table_name2 where restrictions ;注意:查询的结果集合,列数 / 类型 / 顺序 要和 insert into 后面的表相匹配;列的名字不要求相同; create table student1(id int , …...

【医院运营统计专题】3.解码医院运营统计:目标、原则与未来蓝图

医院成本核算、绩效管理、运营统计、内部控制、管理会计专题索引 一、医院运营统计的关键意义 在医疗行业持续发展与变革的大背景下,医院运营统计作为医院管理的关键组成部分,其重要性愈发凸显。从国内医院的普遍现状来看,运营统计已深度融入日常管理,为医院的有序运转提…...

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_atomic_cmp_set 函数

目录 修正 执行 ./configure 命令时,输出: checking for OS Linux 6.8.0-52-generic x86_64 checking for C compiler ... found using GNU C compiler gcc version: 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) 所以当前环境是 x86_64 于是在 src…...

CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测,光伏功率预测

代码地址:CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测,光伏功率预测 CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测 一、引言 1.1、研究背景和意义 光伏功率预测在现代电力系统中占有至关重要的地位。随着可再生能源…...

【YOLO系列】YOLOv5 NMS源码理解、更换为DIoU-NMS

代码来源:GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite 使用的代码是YOLOv5 6.1版本 参考笔记:YOLOv5改进系列(八) 更换NMS非极大抑制DIoU-NMS、CIoU-NMS、EIoU-NMS、GIoU-NMS 、SIoU-NMS、Soft-…...

Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1)

Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1) import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.HardwareRenderer import android.graphics.PixelFormat import android.graphic…...

【linux学习指南】线程同步与互斥

文章目录 📝线程互斥🌠 库函数strncpy🌉进程线程间的互斥相关背景概念🌉互斥量mutex 🌠线程同步🌉条件变量🌉同步概念与竞态条件🌉 条件变量函数 🚩总结 📝线…...

JavaScript函数与方法详解

目录 一、函数的定义 1. 函数声明 2. 函数表达式 3. 箭头函数 二、函数的调用 1. 调用方式 2. 参数数量的灵活性 三、arguments 对象 1. 基本概念 2. 属性 3. 应用场景 4. 转换为真数组 5. 总结 四、Rest参数 1. 基本概念 2. 特点 3. 应用场景 4. 总结 五、变…...

【论文笔记】ZeroGS:扩展Spann3R+GS+pose估计

spann3r是利用dust3r做了增量式的点云重建,这里zeroGS在前者的基础上,进行了增量式的GS重建以及进行了pose的联合优化,这是一篇dust3r与GS结合的具有启发意义的工作。 abstract NeRF和3DGS是重建和渲染逼真图像的流行技术。然而,…...

AtCoder - arc058_d Iroha Loves Strings解答与注意事项

链接:Iroha Loves Strings - AtCoder arc058_d - Virtual Judge 利用bitset这一数据结构,定义bitset类型的变量dp[i]表示第i到n个字符串能拼成的字符串长度都有哪些,比如00100101,表示能拼成的长度有0,2,5,&#xff0…...

企业使用统一终端管理(UEM)工具提高端点安全性

什么是统一终端管理(UEM) 统一终端管理(UEM)是一种从单个控制台管理和保护企业中所有端点的方法,包括智能手机、平板电脑、笔记本电脑、台式机和 IoT设备。UEM 解决方案为 IT 管理员提供了一个集中式平台,用于跨所有作系统和设备类型部署、配置、管理和…...

Leetcode 算法题 9 回文数

起因, 目的: 数学法。 % 求余数, 拆开组合,组合拆开。 这个题,翻来覆去,拆开组合, 组合拆开。构建的过程。 题目来源,9 回文数: https://leetcode.cn/problems/palindrome-number…...

设计模式Python版 命令模式(上)

文章目录 前言一、命令模式二、命令模式示例 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式:关注类和对象之间的组合&…...

C语言之循环结构:直到型循环

C语言 循环结构 直到型循环的实现 特点:先执行,后判断,不管条件是否满足,至少执行一次。典型代表:do…while,goto(已淘汰,不推荐使用) do…while 语法: d…...

细说STM32F407单片机RTC的备份寄存器原理及使用方法

目录 一、备份寄存器的功能 二、示例功能 三、项目设置 1、晶振、DEBUG、CodeGenerator、USART6 2、RTC 3、NVIC 4、GPIO 及KEYLED 四、软件设计 1、main.h 2、main.c 3、rtc.c 4、keyled.c、keyled.h 五、运行调试 本实例旨在介绍备份寄存器的作用。本实例继续使…...

MATLAB计算反映热需求和能源消耗的度数日指标(HDD+CDD)(全代码)

目录 度数日(Degree Days, DD)概述计算公式MATLAB计算代码调用函数1:计算单站点的 CDD参考度数日(Degree Days, DD)概述 度数日(Degree Days, DD)是用于衡量建筑、城市和地区的热需求和能源消耗模式的指标。它分为两部分: 加热度日(Heating Degree Days, HDD):当室…...

接口测试中缓存处理策略

在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂&#xff…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...