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

Java 多线程之 CAS(Compare and Set),实现无锁优化,自旋锁/乐观锁

文章目录

    • 一、概述
    • 二、JDK 的 Unsafe 类
    • 三、ABA 问题

一、概述

  • CAS(Compare and Swap)是一种并发编程中的原子操作(synchronized 也使用了 CAS),用于实现多线程环境下的同步和数据共享。CAS提供了一种高效的并发控制机制,可以避免传统锁机制的开销和问题。

  • CAS操作包括三个操作数:内存位置(通常是共享的变量)、旧的预期值和新的值。

    • CAS操作会先比较内存位置上的值与旧的预期值是否相等,如果相等,则将新的值写入该内存位置;如果不相等,则说明其他线程已经修改了该内存位置的值,CAS操作失败,不会进行写入操作。
  • CAS的优势和应用场景如下:

    1. 非阻塞:CAS是一种非阻塞的原子操作,不会引起线程的阻塞和切换,提高了并发性能。

    2. 原子性:CAS操作是原子的,要么成功执行写入操作,要么失败不写入,不存在中间状态。

    3. 无锁:CAS不需要使用传统锁机制(如互斥锁)来保护共享资源,避免了锁带来的线程阻塞和上下文切换开销。

    4. 并发控制:CAS可以用于并发控制,例如实现线程安全的计数器、自旋锁、无锁队列等数据结构。

    5. 无死锁:由于CAS不使用锁,因此不存在死锁的问题。

  • 尽管CAS具有上述优势,但也存在一些限制和注意事项:

    1. ABA问题:CAS只能检测到预期值是否相等,无法感知到变量值的修改过程中是否发生了其他的并发修改,可能会引发ABA问题。

    2. 自旋次数:在CAS操作失败时,为了尝试成功,可能会进行自旋操作,如果自旋次数过多,会消耗过多的CPU资源。

    3. 适用性:CAS适用于共享变量的简单操作,对于复杂的操作可能不适合使用CAS。

  • java.util.concurrent.atomic.Atomic* 开头的类都用 CAS 实现无锁优化。

二、JDK 的 Unsafe 类

  • Unsafe 提供了一系列低级的、直接操作内存和线程的方法,属于 Java 的核心库之一。由于 Unsafe 提供了直接操作内存和线程的能力,因此它具有很大的潜在危险性,一般建议开发者避免直接使用它,尽量使用更高级别的抽象和标准库提供的功能。

  • 下面是 Unsafe 类的一些常见用途:

    • CAS 操作:Unsafe 提供了一系列的 CAS(Compare and Swap)操作方法,用于实现原子性操作,如原子更新字段、原子更新数组等。

      // unsafe 类使用 CAS 的方法的代码片段
      public final class Unsafe {public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
      }
      
    • 直接内存操作:Unsafe 提供了分配和释放直接内存的方法,可以绕过 Java 堆内存的管理,直接操作底层的内存区域。有allocateMemory、freeMemory、putXX、pageSize类似于C语言中malloc,free等方法。

    • 线程操作:Unsafe 提供了线程的挂起、恢复、创建和销毁等方法,可以直接操作线程。

    • 数组操作:Unsafe 可以直接操作数组的内存,并提供了一些方法来获取数组元素的偏移地址、更新数组元素等。

    • 内存屏障操作:Unsafe 提供了内存屏障(Memory Barrier)的操作方法,用于控制内存的可见性和指令重排序。

    • 直接生类实例allocateInstance,直接操作类或实例变量objectFieldOffset、getInt、getObject,CAS相关操作weakCompareAndSetObject Int Long。

三、ABA 问题

ABA 问题 对值类型没有问题,有问题的是对象类型。

  • ABA 问题描述

    • ABA 问题是指在并发环境下,当一个变量的值从 A 变为 B,然后再变回 A,导致某些操作无法正确检测到中间的变化。
    • ABA 问题的典型场景是使用 CAS(Compare and Swap)操作时发生。CAS 操作涉及比较当前内存位置的值与期望值,如果相等,则进行交换。然而,在一个线程执行 CAS 操作的过程中,其他线程可能修改了内存位置的值,然后又恢复为原始值,这样 CAS 操作将会成功,但实际上内存位置的值已经发生了变化。
  • 下面一个简化的示例来说明 ABA 问题:

    • 假设有两个线程 T1 和 T2,共享一个变量 value 的初始值为 A。执行过程如下:
      • (1)T1 读取 value 的当前值 A。
      • (2)在 T1 进行 CAS 操作之前,T2 修改 value 的值为 B。
      • (3)T2 又将 value 的值修改回 A。
      • (4)T1 执行 CAS 操作,发现 value 的当前值仍然是 A,CAS 操作成功。
    • 在这个例子中,T1 使用 CAS 操作时,期望值是 A,实际上经历了从 A 到 B 再到 A 的变化。尽管 CAS 操作成功,但是它无法感知到中间的 B 的变化,从而可能导致意外的结果。
  • ABA 问题可能会对某些场景产生影响,例如使用 CAS 操作来实现并发数据结构,或者在实现一些复杂的算法时。为了解决 ABA 问题,需要额外的手段来检测变化,例如使用版本号、标记位或引入额外的同步机制。

  • 在 Java 中,AtomicStampedReference 类是专门设计用于解决 ABA 问题的。它通过引入版本号来区分不同的状态,从而检测到变化。

相关文章:

Java 多线程之 CAS(Compare and Set),实现无锁优化,自旋锁/乐观锁

文章目录 一、概述二、JDK 的 Unsafe 类三、ABA 问题 一、概述 CAS(Compare and Swap)是一种并发编程中的原子操作(synchronized 也使用了 CAS),用于实现多线程环境下的同步和数据共享。CAS提供了一种高效的并发控制机…...

python之pyqt专栏1-环境搭建

#python pyqt# python:3.11.6 pycharm:PyCharm Community Edition 2023.2.5 pyqt6 python安装 官网下载:Python Releases for Windows | Python.org pycharm社区版安装 官网地址:Download PyCharm: Python IDE for Professional…...

Spring Cloud LoadBalancer 简单介绍与实战

前言 本文为SpringCloud的学习笔记,如有错误,希望各位高手能指出,主要介绍SpringCloudLoadBalancer的基本概念和实战 文章目录 前言什么是LoadBalancer负载均衡分类服务端负载均衡客户端负载均衡服务端负载均衡和客户端负载均衡的优缺点 常见…...

私域流量解决方案分享

...

Scala---WordCount

一、创建Maven项目导入pom.xml文件 安装Maven仓库管理工具,版本要求是3.2版本以上。新建Maven项目,配置pom.xml。导入必要的包。 二、Spark-Scala版本的WordCount 1.val conf new SparkConf() 2.conf.setMaster("local") 3.conf.setAppNam…...

GTC2023全球流量大会蓄势待发,菊风在7B57展位等你!

第六届 GTC 全球流量大会(以下简称 GTC2023)将于12月5日- 6日,在深圳福田会展中心7&8号馆举办。 据悉,本届大会将是历届以来规模最大、参与人数最多、跨境出海资源最丰富的一次行业盛会。7、8 号馆共 15000 平方米&am…...

喜讯!云起无垠成为国家信息安全漏洞库(CNNVD)技术支撑单位

近日,云起无垠凭借其在漏洞挖掘、漏洞检测以及漏洞修复等领域的卓越表现,荣获“国家信息安全漏洞库(CNNVD)技术支撑单位等级证书(三级)”,正式成为CNNVD技术支撑单位。 中国国家信息安全漏洞库&…...

cc linux用root用户执行chmod 777 -R ./提示 Operation not permitted怎么办?

如果你作为 root 用户执行 chmod 777 -R ./ 命令时收到 “Operation not permitted” 错误,可能有几个原因: 不可更改 (Immutable) 文件属性: 文件可能被设置为不可更改。即使是 root 用户也不能修改这些文件的权限。使用 lsattr 命令查看文件…...

scrapy框架流程

1、Scrapy从Spider子类中提取start_url,然后构造为request请求对象 2、将request请求对象传递给爬虫中间件 3、将request请求对象传递给Scrapy引擎(核心代码) 4、将request请求对象传递给调度器(它负责对多个request安排,好比交…...

802.11 帧的Reason Code 位和Status Code 位

Reason Code 位 当对方不适合加入网络时,工作站会送出 Disassociation(解除连接)或 Deauthentication(解除身份认证)帧作为应答。这些帧当中包含一个长度 16bit 的 Reason Code(原因代码)位&am…...

骨传导能保护听力吗?为什么说骨传导耳机可以保护听力?

由于骨传导耳机的特殊传声方式,是可以保护听力的。 首先了解下骨传导耳机的传声方式是什么: 骨传导耳机是通过骨骼震动传导技术,将声音传至颅骨,然后通过颅骨传导到内耳,直接刺激听觉神经,使人感知到声音…...

【iOS】实现评论区展开效果

文章目录 前言实现行高自适应实现评论展开效果解决cell中的buttom的复用问题 前言 在知乎日报的评论区中,用到了Masonry行高自适应来实现评论的展开,这里设计许多控件的约束问题,当时困扰了笔者许久,特此撰写博客记录 实现行高自…...

POE交换机——电源解决方案-升压控制器\降压控制器\中高压降压转换器

PoE是一种有线以太网供电技术,使用于数据传输的网线同时具备直流供电的能力,PoE供电具有可靠、连接简捷、标准统一的优势。越来越多的工业物联网设备开始采用PoE供电, 如IP电话、网络视频监控以及无线以太网设备等。 PoE交换机是一种用于提供…...

[C/C++]数据结构 循环队列

前言: 队列是一种具有先进先出特性的结构,但是当数据出队列以后,前面的空间就无法再次利用了,循环队列就可以解决这个问题 一:概念及结构: 1.循环队列概念 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队…...

Cache学习(2):Cache结构 命中与缺失 多级Cache结构 直接映射缓存

1 Cache名词解释 命中(hit): CPU要访问的数据在Cache中有缓存缺失(miss): CPU要访问的数据在Cache中没有缓存Cache Size:Cache的大小,代表Cache可以缓存最大数据的大小Cache Line&a…...

vue前端前端页面权限验证方式

在Vue应用中使用Vuex(Vue的状态管理库)来存储用户组(user group)和角色(roles)信息是一种合理的做法,特别是在涉及到权限管理和用户身份的情况下。Vuex提供了一个集中式的状态管理方案&#xff…...

jenkins springCloud项目优雅下线

文章目录 场景解决下线请求效果如图贴一个可用的部署脚本 场景 在 Spring Cloud 项目的微服务实例关闭时,需要首先从注册中心设置为下线,避免该服务的消费者继续请求该服务实例,导致请求失败如果我们在服务实例从注册中心取消注册后&#xff…...

indexOf

可以通過String的indexOf判斷是否包括某個字符。 SpringBootTest Slf4j class BaseApplicationTests {Testvoid contextLoads() {log.info("01".indexOf(".")"");log.info("0.1".indexOf(".")"");log.info("…...

STM32分区跳转问题

项目场景: 在OTA中,FLASH通常被划分为以下几种类型 bootloaderiapappbootloaderappapp保存区bootloaderapp1app2 不同的分区方式有不同的有点,但是共同点都是需要执行分区跳转 问题1描述 但在分区跳转过程中遇到过使用不同的编译器不能跳转…...

亿级流量架构服务降级

什么是服务降级 如果看过我前面对服务限流的分析,理解服务降级就很容易了,对于一个景区,平时随便进出,但是一到春节或者十一国庆这种情况客流量激增,那么景区会限制同时进去的人数,这叫限流,那么什么是服务降级呢? 简单来说就是,将一些不太重要的景区项目砍掉,平时就那么三五…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来&#xf…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...