并发编程中的CAS思想

共享变量操作的原子性

分析如下代码片段:

// 获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰。
static volatile int count = 0;public static void add(){count++;
}public static void main(String[] args) throws InterruptedException {// t1线程对count加5000次Thread t1 = new Thread(() -> {for (int i = 0; i < 5000; i++) {add();}});// t2线程对count加5000次Thread t2 = new Thread(() -> {for (int i = 0; i < 5000; i++) {add();}});t1.start();t2.start();// 确保t1、t2都完成t1.join();t2.join();System.out.println(count);  // 正常情况下应该为10000
}

出现线程安全的原因:count++ 包含了三个独立的操作:读取count的值,将值加1,然后将计算结果写入count。这是一个 “读取-修改-写入” 的操作序列

如果计数器的初始值为9,那么在某些情况下,每个线程读到的值都为9,接着执行递增操作,并且都将计数器的值设为10。显然,这并不是我们希望看到的情况,如果有一次递增操作丢失了,计数器的值就将偏差1

本质上线程可能会基于一种 可能失效的观察结果 来做出判断或者执行某个计算

解决思路:要递增一个计数器,你必须知道它之前的值,在将更新结果写回之前,确保其它线程没有修改过这个值

解决方式一:在某个线程修改该变量时,防止其他线程使用这个变量,从而确保其他线程只能在修改操作完成之前或之后读取和修改状态,而不是在修改状态的过程中 (利用synchronized锁

解决方式二:线程在计数器原始值基础上做修改操作,在要把修改后的值写回计数器前,判断此时计数器的值还是不是原始值了(利用CAS思想

​ 若不是,则说明在当前线程执行更新的过程中已经有其它线程修改了计数器,所以当前线程修改的结果值不能再写回。只能终止,再尝试下一轮的修改操作,直到成功

​ 若是,则说明在当前线程执行更新的过程中没有其他线程修改过计数器(此处会产生ABA问题),所以当前线程可以将修改的值写回计数器,修改成功

CAS(比较和交换)本身不就是"先判断,后执行"的操作?如何保证CAS的原子性呢?——底层利用的是 cmpxchg 指令,该指令从底层硬件上确保了 “比较” 和 “交换” 这两个操作的原子性

方式一实现:为 add 方加上 synchronized 锁,缺点:性能较低,当一个线程获取锁后,其它线程只能无条件的阻塞,会伴随着线程的阻塞与唤醒:上下文切换(核心态 --> 用户态)的开销

方式二实现:使用原子类 AtomicInteger 变量,配合它的 getAndAdd 方法(CAS)来实现并发状态下的正确递增操作, 即使操作失败,也没有放弃CPU执行权,不会阻塞。 缺点:可能会出现 ABA 问题

乐观锁与悲观锁

悲观锁:总是认为不加锁,就一定会产生线程安全问题(不加锁,一定会出现问题),这样的话就会伴随线程的阻塞与唤醒:上下文切换(核心态 --> 用户态)的开销

乐观锁:CAS是一种无锁的同步机制(失败了无所谓,大不了重试),可以在不使用锁的情况下实现数据的同步和并发控制,优点:不会导致上下文切换,即使操作失败,也不是直接放弃CPU,而是继续重试

在这里插入图片描述

JUC包下的并发原子类

仿照 AtomicInteger 类,实现并发条件下共享变量递增的线程安全:

public class AtomicIntegerTest {static AtomicInteger count = new AtomicInteger(0);public static void increment() {while (true) {// 旧值int except = count.get();// 要更新的值int update = except + 1;// CASif (count.compareAndSet(except, update))break;}}public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {for (int i = 0; i < 5000; i++) {increment();}}, "t1");Thread t2 = new Thread(() -> {for (int i = 0; i < 5000; i++) {increment();}}, "t2");t1.start();t2.start();// 确保t1、t2都执行完,看到的是最终count的值t1.join();t2.join();System.out.println(count.get());}}

注:这些并发原子类底层实际上使用的是 sun.misc.Unsafe 类里面的 compareAndSwapXxx() 方法包装提供

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

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

相关文章

占地1.1万平,2亿投资的智能仓储系统:高架库、AGV、码垛机器人……

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 我国调味料市场近年来展现出惊人的增长潜力&#xff0c;各大品牌纷纷加大投入&#xff0c;力求在竞争中脱颖而出。 广东美味鲜调味食品有限公司&#xff0c;作为行业内的佼佼者&#…

激活函数、条件熵和最大熵在机器学习的应用

文章目录 摘要Abstractsigmoid 和 softmaxsigmoid和softmax的关系 条件熵最大熵总结 摘要 本周学习内容探讨了神经网络中激活函数的选择及其对梯度消失问题的影响。通过使用 ReLU 函数替代 Sigmoid 函数来改善梯度消失问题的优化方法&#xff0c;同时分析了 Sigmoid、Softmax …

【MySql】-0.1、Unbunt20.04二进制方式安装Mysql5.7和8.0

1、下载Mysql二进制报&#xff08;选择Linux的通用版本&#xff09; mysql官网地址&#xff1a;https://downloads.mysql.com/archives/community/ wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.26-linux-glibc2.12-x86_64.tar wget https://downloads.…

全渠道供应链打造中企业定制开发2+1链动模式S2B2C商城小程序的策略与影响

摘要&#xff1a;本文探讨了全渠道供应链打造对于零售企业的重要性及面临的挑战&#xff0c;着重分析了物流环节整合的难点&#xff0c;并以家电行业为例说明了节假日期间物流对企业经营的影响。同时&#xff0c;引入“企业定制开发21链动模式S2B2C商城小程序”这一关键因素&am…

【Python+Pycharm】2024-Python安装配置教程

【PythonPycharm】2024-Python安装配置教程 一、下载装 Python 1、进入Python官网首页&#xff0c;下载最新的Python版本 Download Python | Python.org 选择对应版本下载 安装 测试安装情况 python如果安装失败 在系统环境变量添加安装路径 where pythonwin7安装路径添加…

C++开发者必看:用Flow-IPC改善进程间通信

进程间通信&#xff08;IPC&#xff09;对于现代计算环境至关重要&#xff0c;这种机制使得多个处理器核心能够同时执行多个线程。IPC的本意是让不同线程甚至独立程序能够高效地共享数据。例如&#xff0c;当我们在线观看流媒体视频时&#xff0c;可能会有一个线程负责视频解码…

JAVA 插入 JSON 对象到 PostgreSQL

博主主页:【南鸢1.0】 本文专栏&#xff1a;JAVA 目录 ​编辑 简介 所用&#xff1a; 1、 确保 PostgreSQL 数据库支持 JSON&#xff1a; 2、添加 PostgreSQL JDBC 驱动 3、安装和运行 PostgreSQL 4、建立数据库的连接 简介 在现代软件开发中&#xff0c;由于 JSON 数据…

闪存学习_1:Flash-Aware Computing from Jihong Kim

闪存学习_1&#xff1a;Flash-Aware Computing from Jihong Kim 前言一、Storage Media&#xff1a;NAND Flash Memory1、概念2、编程和擦除操作3、读操作4、异地更新操作&#xff08;Out-Place Update&#xff09;5、数据可靠性6、闪存控制器&#xff08;SSD主控&#xff09;7…

C++STL-deque、stack、queue、priority_queue

C教学总目录 deque、stack、queue、priority_queue 1、deque2、stack使用介绍3、stack实现4、queue使用介绍5、queue实现6、priority_queue使用介绍7、priority_queue实现8、反向迭代器 1、deque deque是双端队列&#xff0c;我们学习的队列是先进先出的(First in first out)&a…

汽车虚拟仿真软件有哪些?行业软件大盘点!

汽车虚拟仿真是指利用计算机技术&#xff0c;根据汽车的设计、制造、测试、运行等各个环节的需求&#xff0c;建立汽车的数学模型和物理模型&#xff0c;通过软件平台进行可视化、动态化、交互式的模拟和分析&#xff0c;从而实现对汽车性能、功能、品质等方面的预测和评估。汽…

【合肥工业大学】操作系统 习题解析 作业答案(仅作学习与交流/侵删)

第一章习题解析 1&#xff0e;设计现代OS的主要目标是什么&#xff1f; 答&#xff1a;&#xff08;1&#xff09;有效性 &#xff08; 2&#xff09;方便性 &#xff08; 3&#xff09;可扩充性 &#xff08; 4&#xff09;开放性 2&#xff0e; OS 的作用可表现在哪几个方…

【C++动态规划】2435. 矩阵中和能被 K 整除的路径|1951

本文涉及知识点 C动态规划 LeetCode2435. 矩阵中和能被 K 整除的路径 给你一个下标从 0 开始的 m x n 整数矩阵 grid 和一个整数 k 。你从起点 (0, 0) 出发&#xff0c;每一步只能往 下 或者往 右 &#xff0c;你想要到达终点 (m - 1, n - 1) 。 请你返回路径和能被 k 整除的…

matlab读取逐日的1km分辨率中国大陆地区的土壤水数据,并汇总至逐月分辨率

1.前言 ESSD一篇文章介绍了逐日的土壤水数据&#xff1a; ESSD - A 1 km daily soil moisture dataset over China using in situ measurement and machine learning 图片来源&#xff1a;Li et al., 2022, ESSD 中国大陆地区的土壤水的数据下载地址&#xff1a; 国家青藏高…

用Pyhon写一款简单的益智类小游戏——2048

文字版——代码及讲解 代码—— import random# 初始化游戏棋盘 def init_board():return [[0] * 4 for _ in range(4)]# 在棋盘上随机生成一个2或4 def add_new_tile(board):empty_cells [(i, j) for i in range(4) for j in range(4) if board[i][j] 0]if empty_cells:i,…

C++类和对象上

1. 类的定义 1.1 类定义格式 • class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员&#xff1a;类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。…

目标追踪DeepSort

一、卡尔曼滤波 你可以在任何对某个动态系统有 “不确定信息” 的地方使用卡尔曼滤波器&#xff0c;并且可以对系统下一步的行为做出 “有根据的猜测”。即使混乱的现实干扰了你所猜测的干净运动&#xff0c;卡尔曼滤波器通常也能很好地确定实际发生了什么。它还可以利用你可能…

Python爬虫:揭开淘宝商品描述的神秘面纱

在这个信息爆炸的时代&#xff0c;我们每天都在和时间赛跑。作为一名Python开发者&#xff0c;你是否曾梦想拥有超能力&#xff0c;能够瞬间揭开淘宝商品描述的神秘面纱&#xff1f;今天&#xff0c;就让我们一起化身为代码界的“福尔摩斯”&#xff0c;使用Python爬虫技术&…

消息队列面试——打破沙锅问到底

消息队列的面试连环炮 前言 你用过消息队列么&#xff1f;说说你们项目里是怎么用消息队列的&#xff1f; 我们有一个订单系统&#xff0c;订单系统会每次下一个新订单的时候&#xff0c;就会发送一条消息到ActiveMQ里面去&#xff0c;后台有一个库存系统&#xff0c;负责获取…

HTMLCSS:3D旋转动画机器人摄像头

效果演示 创建了一个3D机器人摄像头效果。 HTML <div class"modelViewPort"><div class"eva"><div class"head"><div class"eyeChamber"><div class"eye"></div><div class&quo…

docker占用磁盘过多问题

我在windows系统上用docker&#xff0c;安装在C盘环境下&#xff0c;我发现C盘占用了大量的空间&#xff0c;查找后发现是docker的映像文件占用的&#xff0c;于是开始清理&#xff0c;中间还踩个坑&#xff0c;记录一下&#xff0c;下次需要的时候方便找。 踩坑 我本想移动映…