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

JUC-CAS

1. CAS概述

CAS(Compare ans swap/set) 比较并交换,实现并发的一种底层技术。它将预期的值和内存中的值比较,如果相同,就更新内存中的值。如果不匹配,一直重试(自旋)。Java.util.concurrent.atomic包下的原子类都使用了CAS算法

2. CAS原理

CAS具体的操作是将预期的值和内存中真实的值进行比较,如果相同就更新值。如果不相同就重试(自旋)。
CAS是通过Unsafe的compareAndSwap方法实现的,底层实现是CPU原子指令cmpxchg,不会造成数据不一致的问题。
CAS依靠底层硬件实现的无锁原子算法。比synchronized重量级锁性能更好。

3. CAS与自旋锁

3.1 前置知识:原子引用类AtomicReference

将自定义的类型变成原子类,能够进行cas操作。

    public static void main(String[] args){AtomicReference<User> atomicReference = new AtomicReference<>();User z3 = new User("z3",22);User li4 = new User("li4",28);atomicReference.set(z3);System.out.println(atomicReference.compareAndSet(z3, li4)+"\t"+atomicReference.get().toString());System.out.println(atomicReference.compareAndSet(z3, li4)+"\t"+atomicReference.get().toString());}

3.2 CAS实现一个自旋锁:A线程持有锁,B线程自旋等待直到A释放锁。

/*** 题目:实现一个自旋锁,复习CAS思想* 自旋锁好处:循环比较获取没有类似wait的阻塞。** 通过CAS操作完成自旋锁,A线程先进来调用myLock方法自己持有锁5秒钟,B随后进来后发现* 当前有线程持有锁,所以只能通过自旋等待,直到A释放锁后B随后抢到。*/
public class SpinLockDemo
{AtomicReference<Thread> atomicReference = new AtomicReference<>();public void lock(){Thread thread = Thread.currentThread();System.out.println(Thread.currentThread().getName()+"\t"+"----come in 等待锁");while (!atomicReference.compareAndSet(null, thread)) {}System.out.println(Thread.currentThread().getName() + "\t 拿到锁");}public void unLock(){Thread thread = Thread.currentThread();atomicReference.compareAndSet(thread,null);System.out.println(Thread.currentThread().getName()+"\t"+"----task over,释放锁...");}public static void main(String[] args){SpinLockDemo spinLockDemo = new SpinLockDemo();new Thread(() -> {spinLockDemo.lock();//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }spinLockDemo.unLock();},"A").start();//暂停500毫秒,线程A先于B启动try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }new Thread(() -> {spinLockDemo.lock();spinLockDemo.unLock();},"B").start();}
}

核心思想:

  • 加锁:开始的时候,内存中的值为NULL,一旦有线程进入,预期值为NULL,和真实值匹配将内存设置为当前线程值。(此时其他线程进来后预期值NULL,但是真实值已经被修改所以会自旋,这为加锁)
  • 解锁: 释放锁之后,重新设置内存的值为NULL,让其他线程能够进入从而修改

运行结果:
在这里插入图片描述

CAS和synchronized比较

CAS线程不会阻塞,线程一直自旋。
Synchronized会阻塞,会进行线程的上下文切换非常耗费资源。

CAS缺点

循环时间长开销大

CAS如果预测值和真实值不一样,将一直自旋。导致循环CPU开销大。

ABA问题

ABA问题顾名思义就是将线程1在进行CAS操作的时候,另一个线程2已经将A修改为B又快速修改回A,导致一个线程并未发现中间修改过仍能正常进行CAS比较和修改。

ABA问题解决方案

原子时间戳引用:给每次修改都加上一个时间戳(版本号),CAS操作的时候不仅要比较预测值和真实值,还要比较预测版本号和真实版本号。

new AtomicStampedReference().compareAndSet(V   expectedReference,V   newReference,int expectedStamp,int newStamp)

CAS注意事项

CAS只能保证原子性,不能保证变量的可见性。要配合volatile使用,保证共享变量的可见性。
CAS适用于并发量不高,多核CPU的情况。并发量增高,CAS自旋会导致消耗CPU资源。这时候用LongAdder

相关文章:

JUC-CAS

1. CAS概述 CAS(Compare ans swap/set) 比较并交换&#xff0c;实现并发的一种底层技术。它将预期的值和内存中的值比较&#xff0c;如果相同&#xff0c;就更新内存中的值。如果不匹配&#xff0c;一直重试&#xff08;自旋&#xff09;。Java.util.concurrent.atomic包下的原…...

Effective C++——关于重载赋值运算

令operator返回一个*this的引用 在重载,,*等运算符时&#xff0c;令其返回一个指向this的引用。 class MyClass {int* val; public:MyClass(int i) : val(new int(i)){}MyClass():val(new int(0)){}void print() {cout << *val << endl;}MyClass& operator(co…...

vscode debug

需要对GitHub上的工程debug。 所以花时间看了下,参考了bili视频和chatgpt的解答。 chatgpt给的步骤 要在 VS Code 中调试 C++ 项目,可以按照以下步骤进行设置和操作: 确保已安装 C++ 扩展:在 VS Code 中选择 “Extensions”(或使用快捷键 Ctrl+Shift+X),搜索并安装官…...

数据库选型其实技术维度不太重要

看到这个标题可能觉得我在乱说&#xff0c;数据库选型要从多个角度和维度看来&#xff0c;还有各种POC。很多供应商朋友告诉我POC是一个漫长的过程&#xff0c;非常痛苦&#xff0c;要解决各种技术问题。怎么能说和技术无关呢&#xff1f; 因为从我的经历和周围听说的经验来说…...

【C++】入门(二)

前言&#xff1a; c基础语法&#xff08;下&#xff09; 文章目录 五、引用5.1 引用概念5.2 引用使用规则5.3 常引用5.4 引用的使用场景5.5 引用和指针的区别 六、内联函数6.1 概念6.2 内联函数的特性 七、auto关键字&#xff08;C11&#xff09;7.1 概念7.2 使用规则7.3 用于f…...

Nginx 代理服务路径带/和不带/的问题

nginx初始配置如下 server {listen 6087;location / {#网站主页路径。此路径仅供参考&#xff0c;具体请您按照实际目录操作。#例如&#xff0c;您的网站运行目录在/etc/www下&#xff0c;则填写/etc/www。#允许跨域请求的域&#xff0c;* 代表所有add_header Access-Control-…...

C# CefSharp 输入内容,点击按钮,并且滑动。

前言 帮别人敲了个Demo,抱试一试心态&#xff0c;居然成功了&#xff0c;可以用。给小伙伴们看看效果。 遇到问题 1&#xff0c;input输入value失败&#xff0c;里面要套了个事件&#xff0c;再变换输入value。后来用浏览器开发工具&#xff0c;研究js代码&#xff0c;太难了&a…...

历经15年,比特币以强势姿态进军华尔街!270亿美元投资狂潮引发市场震荡!

本月&#xff0c;比特币庆祝了它的15岁生日&#xff0c;并以强势的姿态进军华尔街。最近美国交易所开始交易的比特币交易所交易基金&#xff08;ETF&#xff09;&#xff0c;已经获得了投资者的广泛接受。这一进展标志着比特币作为一种年轻资产迈向成熟的重要里程碑。 根据Glas…...

GBASE南大通用的接口程序GBase ADO.NET

GBase ADO.NET 是一个提供.NET 应用程序与 GBase 数据库之间方便、高效、 安全交互的接口程序&#xff0c;使用 100%纯 C#编写&#xff0c;并继承了 Microsoft ADO.NET 类。 开发人员可以使用任何一种.NET 开发语言&#xff08;C#、VB.NET、F#&#xff09;通过 GBase ADO.NET 操…...

算法训练营Day57(回文子串--总结DP)

647. 回文子串 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int countSubstrings(String s) {int len s.length();//i到j这个子串是否是回文的boolean [][] dp new boolean[len][len];int res 0;for(int i len-1;i>0;i--){for(int …...

使用OpenCV从一个矩阵提取子矩阵

介绍opencv的两个函数&#xff1a;Range()和Rect() Range()是用于表示一个范围的类。它的构造函数有两个整数参数&#xff0c;分别表示范围的起始和终止索引。这个范围包括起始索引但不包括终止索引。 cv::Range(int start, int end); /* 在OpenCV中&#xff0c;cv::Range() …...

微信云托管:基本使用指南

微信云托管 &#x1f6a8;推荐&#xff1a;微信云托管&#xff1a;基本使用指南 确实是个好平台&#xff0c;部署个项目很简易&#xff0c;免去了很多运维上的事情。 一、微信云托管 github 流水线配置 和 端口号 首先&#xff0c;这里的主体(宿主机)&#xff0c;指的就是你的…...

WEB前端IDE的使用以及CSS的应用

IDE的使用 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, i…...

python中排序函数sorted的简单运用

# 假设a里面的()分别对应的x,y,w,h 即 (x,y,w,h) a [(2,3,1,2),(4,1,2,2),(1,6,2,1)] # a:传入的列表 # key 排序的数据 keylambda x:x[n] 是固定写法,里面的n代表你按照()中第几个数据的值排序 # eg&#xff1a;我们这里是x:x[0]表示我们按x排序, 如果改成x:x[1]则按y排序 # …...

k8s的helm

1、在没有helm之前&#xff0c;部署deployment、service、ingress等等 2、helm的作用&#xff1a;通过打包的方式&#xff0c;deployment、service、ingress这些打包在一块&#xff0c;一键部署服务、类似于yum功能 3、helm&#xff1a;官方提供的一种类似于仓库的功能&#…...

[MySQL]基础的增删改查

目录 1.前置介绍 2.数据库操作 2.1显示当前数据库 2.2创建数据库 2.3 使用数据库 2.4 删除数据库 3.常用数据类型 3.1整型和浮点型 3.2字符串类型 4.表的操作 4.1查看表结构 4.2创建表 4.3删除表 5.重点 5.1操作数据库 5.2常用数据类型 5.3操作表 1.前置介绍 …...

简易播放器 以及触发的异常

jl 1.0.jar 架包导入步骤&#xff1a; 1.读取到MP3音频文件 2.创建播放器对象,传入音频文件 3.开始播放 package com.ztt.Demo01;import java.io.FileInputStream; import java.io.FileNotFoundException;import javazoom.jl.decoder.JavaLayerException; import javazoom.jl.…...

【Flutter跨平台插件开发】如何实现kotlin跟C++的相互调用

【Flutter跨平台插件开发】如何实现kotlin跟C的相互调用 kotlin 调 c 在 Kotlin 中&#xff0c;可以使用 JNI (Java Native Interface) 来调用 C 代码 调用步骤: 创建 C 文件并实现函数。 // example.cpp #include <jni.h>extern "C" JNIEXPORT jstring J…...

Apache SeaTunnel社区荣获“2023快速成长开源项目”奖项

在这个开源理念推动技术创新和全球协同发展的时代&#xff0c;SeaTunnel社区在开放原子开源基金会举办的2023年开源项目评选中脱颖而出&#xff0c;荣获“2023快速成长开源项目”殊荣。 这个奖项不仅仅是对Apache SeaTunnel社区过去一年发展速度和质量的认可&#xff0c;更是对…...

Unity 桥接模式(实例详解)

文章目录 示例1&#xff1a;角色与装备系统示例2&#xff1a;UI控件库示例3&#xff1a;渲染引擎模块示例4&#xff1a;AI决策树算法示例5&#xff1a;物理模拟引擎 在Unity游戏开发中&#xff0c;桥接模式&#xff08;Bridge Pattern&#xff09;是一种设计模式&#xff0c;它…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...