CAS和synchronized原理

synchronized与CAS

  • Synchronized 原理
    • 加锁工作过程
    • 一些优化
  • CAS
    • 实现原子类
  • 小结

Synchronized 原理

  1. synchronized 既可以是乐观锁, 也可以是悲观锁.
  2. synchronized 既可以是轻量级锁, 也可以是重量级锁.
  3. synchronized 重量级锁是由系统的互斥锁实现的; 轻量级锁是基于自旋锁实现的.
  4. synchronized 是非公平锁(不会遵守先来后到).
  5. synchronized 是可重入锁(内部会记录哪个线程拿到了锁, 记录引用计数).
  6. synchronized 不是读写锁.

Synchronized的内部实现策略?
可能会产生一系列的"自适应"的过程, 叫做锁升级.
无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁.

加锁工作过程

  • 偏向锁: 偏向锁不会真的加锁, 只是做了一个标记.如果有别的线程来竞争了, 才会真的加锁.如果没有别的线程竞争, 就始终不会真的加锁.(能不加就不加)
  • 轻量级锁: synchronized通过自旋锁的方式实现轻量级锁.
    一个线程把锁占据之后, 另一个线程就会按照自旋的方式反复查询当前锁是否被释放了,
    但是, 如果这把锁的线程越来越多了(锁竞争更激烈了), 就会升级为重量级锁.

一些优化

  • 锁消除: 编译器会智能的判定当前代码是否要加锁, 如果你写了加锁, 实际上没有必要加锁, 就会把加锁操作自动删除掉.
  • 锁粗化: 锁的粒度?
    我们一般认为, 如果加锁操作中包含的实际要执行的代码越多, 就认为锁的粒度越大.
    锁的粒度越小, 并发程度就更高.
for(...) {synchronized (this) {count++;}
}

锁的粒度越大, 效率就越高.

synchronized (this) {for(...) {count++;}		
}

CAS

CAS(Compare and swap).
假设内存中的原数据V, 旧的预期值A, 需要修改的新值B.
1. 比较AV是否相等.
2. 如果比较相等,B写入V.
3. 返回操作是否成功.

使用CAS伪代码来辅助理解CAS的工作流程, 不是原子性代码.

// address: 内存地址. expectValue: 寄存器中的值. swapValue: 相等就替换的值
boolean CAS(address, expectValue, swapValue) {if(&address == expectValue) {&address = swapValue;return true;}return false;
}

但是这段代码逻辑, 是通过一条cpu指令完成的, 具备原子性, 就给我们编写线程安全代码, 打开了新大门.

实现原子类

标准库中提供了一组原子类, 最典型的是AtomicInteger类.
在这里插入图片描述

在这里插入图片描述

有两个构造方法.
// 设置初值为0
AtomicInteger();
// 设置初值为initialValue
AtomicInteger(int initialValue);

提供了一系列方法:

// 前置++
public final int getAndIncrement() {Atomically increments by one the current value.Returns:the previous value
}
// 前置--
public final int getAndDecrement() {Atomically decrements by one the current value.Returns:the previous value
}
// 后置++
public final int incrementAndGet() {Atomically increments by one the current value.Returns:the updated value
}
// 后置--
public final int decrementAndGet() {Atomically decrements by one the current value.Returns:the updated value
}
public class Demo28 {// 设置初值为0private static AtomicInteger count = new AtomicInteger(0);public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> {for (int i = 0; i < 5000; i++) {count.getAndIncrement();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 5000; i++) {count.getAndIncrement();}});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println(count);}
}
// 结果是10000, 是原子性的.

下面使用伪代码实现原子类:

class AtomicInteger {private int value;// 前置++public int getAndIncrement() {int oldValue = value;while ( CAS(value, oldValue, oldValue+1) != true) {oldValue = value;}return oldValue;}
}
// oldValue, value, oldValue+1 都是寄存器中的值
// 如果value和oldValue相等, 就return oldValue
// 如果不等, 就把oldValue = value;

为啥会出现oldValue != value的情况呢??
因为很可能出现有别的线程穿插在两段代码之间, 把它修改了.
在这里插入图片描述
以上的图很好的描绘了如何修改代码的…

当两个线程并发的执行++操作时,如果不加任何限制,其一,就会出现串行化;
其二, 就会出现穿插, 会使结果出现问题.
通过加锁保证线程安全,强制避免穿插.
而原子类CAS保证线程安全,借助CAS来识别当前是否出现了穿插情况,如果没穿插,此时直接修改.
如果穿插了,就会重新回去内存中的值,再次尝试修改. 
多个CAS线程访问内存时,一定会有先后顺序的.
因为多个cpu在操作同一个资源, 也会涉及到锁竞争(指令级别的锁).synchronized实现的
锁要轻量许多(cpu内部实现的机制).

小结

本文讲述了synchronized的原理, 以及CAS实现原子类.
博主会在下篇博客中更新CAS实现自旋锁, 以及ABA问题和相关面试题.
希望有收获的小伙伴多多支持!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++学习进阶:智能指针

目录 前言&#xff1a; 1.知识引入 1.1.异常安全问题 1.2.RALL和智能指针雏形 2.智能指针的发展 2.1.auto_ptr的引入 2.2.unique_ptr的引入 2.3.救世主shared_ptr&#xff08;重点&#xff09; 2.4.weak_ptr的引入&#xff08;重点&#xff09; 2.5.测试函数 3.定制删…

学习Python先从了解Python开始

Python是一种高级编程语言&#xff0c;它的语法简洁易读&#xff0c;功能强大&#xff0c;应用领域广泛。Python不仅适用于数据科学、机器学习、Web开发等领域&#xff0c;还可以用于自动化脚本编写、游戏开发等。在本文中&#xff0c;我们将探讨Python的特点、应用领域以及未来…

网工内推 | 兴业银行总行正编,科技运维部,硕士以上学历

01 兴业银行 招聘岗位&#xff1a;安全渗透专家 职责描述&#xff1a; 1.负责牵头组织本行红蓝对抗、攻防演练等工作&#xff1b; 2.负责牵头制定有效的渗透测试方案&#xff0c;开展对本行防御体系的验证工作&#xff1b; 3.负责牵头组织本行各类应用系统的渗透测试与漏洞扫…

图神经网络与分子表征:7. LEFTNet

在执行性质预测任务时&#xff0c;我们需要考虑两个问题&#xff1a;1. 如何正确的将图结构进行编码&#xff1f;2. 如何汇聚编码信息预测整个分子的任务&#xff1f; LEFTNet 就是通过回答上述问题来进行模型设计的。 原文地址 算法设计 原文中&#xff0c;作者定义了三个图…

小米安卓春招面试一面

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 1.多态 2.hashmap&#xff0c;hashtable和concurrenthashmap&#xff0c;问的定义实现和区别 3.jvm的运行…

02 - ArcGIS For JavaScript-矢量数据的符号化处理(Symbol)

文章目录 综述Symbol的分类Point的符号化Point符号化为二维几何&#xff1a;Point位图符号化&#xff1a;Point的三维结合符号化Point 符号化为GLTF模型 PolylineSymbol-线符号化基本样式管道样式墙体样式条带样式方管样式 PolygonSymbol-面符号化水面效果拉伸效果填充效果 Mes…

PCB----Allegro软件使用小技巧

1.修改画好的同面积&#xff1a; 2.修改铜的网络&#xff0c;或者铺铜铺错网络了&#xff1a; 点击需要修改的铜 在点击要修改成的网络 3.铺铜需要注意&#xff1a; 铜片和铜片之间间隔2个点&#xff08;点设置6.25&#xff0c;如下图1-2&#xff1a;&#xff09; 每一个单独的…

差速机器人模型LQR 控制仿真——路径模拟

LQR路径跟踪要求路径中带角度&#xff0c;即坐标&#xff08;x,y,yaw&#xff09;&#xff0c;而一般我们的规划出来的路径不带角度。这里通过总结相关方法&#xff0c;并提供一个案例。 将点路径拟合成一条完整的线路径算法 将点路径拟合成一条完整的线路径是一个常见的问题…

ai智能电话机器人是如何自主学习的

电话机器人的出现&#xff0c;帮助很多传统电销行业企业进入新的发展阶段。它主要通过语音识别和针对语意的理解识别客户所说的内容&#xff0c;针对性的回答问题&#xff0c;为企业高效筛选意向客户。除了电话机器人语音识别之外&#xff0c;电话机器人能够自主学习&#xff0…

大模型推理性能优化之KV Cache解读

0. 引言 做大模型性能优化的一定对KV Cache不陌生,那么我们对这个技术了解到什么程度呢?请尝试回答如下问题: KV Cache节省了Self-Attention层中哪部分的计算?KV Cache对MLP层的计算量有影响吗?KV Cache对block间的数据传输量有影响吗?本文打算剖析该技术并给出上面问题…

每日一题 — 最小覆盖子串

76. 最小覆盖子串 - 力扣&#xff08;LeetCode&#xff09; 解法一&#xff1a;暴力遍历哈希表 解法二&#xff1a;滑动窗口哈希表 定义left和right初始化为零&#xff0c;固定left&#xff0c;先向右遍历right&#xff0c;放到哈希表中这个时候我们需要统计有效字符的个数&…

五种主流数据库:集合运算

关系型数据库中的表与集合理论中的集合类似&#xff0c;表是由行&#xff08;记录&#xff09;组成的集合。因此&#xff0c;SQL 支持基于数据行的各种集合运算&#xff0c;包括并集运算&#xff08;Union&#xff09;、交集运算&#xff08;Intersect&#xff09;和差集运算&a…

chromedriver最新版下载地址

地址1.百度网盘 链接(提取码&#xff1a;2vo3)&#xff1a;百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com…

数据很重要,ASM磁盘组损坏,使用AMDU来抢救

欢迎关注“数据库运维之道”公众号&#xff0c;一起学习数据库技术! 本期将为大家分享“数据很重要&#xff0c;ASM磁盘组损坏&#xff0c;使用AMDU来抢救”的处置案例。这个案例对个人来说比较经典&#xff0c;下面我将把自己的处理思路进行整理与总结。 环境信息&#xff1…

STC15系列库中两个自定义函数的更新

一、事件背景 1.出于操作IO口的需求&#xff0c;在LED操作例程当中我在官方库当中添加了两个gpio函数&#xff1b;详见基于STC15系列库操作LED灯-CSDN博客&#xff1b;在新的例程中察觉到两个函数操作的局限性&#xff0c;于是将两个函数内容进行相应修改&#xff0c;使其能适…

安装Milvus的可视化工具Attu教程

提供两种方式来安装可视化工具Attu 一、docker安装 # 执行命令&#xff0c;加个 -d 在后台运行 docker run -d -p 8000:3000 -e MILVUS_URL127.0.0.1:19530 zilliz/attu:v2.2.8 至此安装完成&#xff01; 浏览器输入地址 http:127.0.0.1:8000即可访问 Attu主页 如果拉取最新…

I设计需要学习什么?我们应该掌握什么软件?

I设计需要学习什么&#xff1f;我们应该掌握什么软件&#xff1f; 许多新人在进入UI设计行业之前都会有很多疑问。我应该学习什么&#xff0c;应该掌握什么软件&#xff1f;如果要学习ui设计&#xff0c;首先应该知道什么是UI设计。“ UI”的原始含义是用户界面&#xff0c;它是…

使用nginx发布tomcat站点

之前我们在访问的时候使用的都是类似http://serverip/test或者http://serverip/jpress这种字样的URL,使用起来比较麻烦,所以呢,我们可以将tomcat和nginx结合在一起,可以通过nginx以下功能发布: 使用nginx url重写使用nginx的反向代理功能一、部署tomcat网站 通过部署两个…

大数据操作第二天

文章目录 大数据命令的方式现在有三个命令的方式 启动一个计算圆周率的jar包方式什么是文件系统数据元数据传统的存储方式分布式存储方式元数据记录文件位置信息副本机制的方式 hafs 存储方式shell 操作大数据的方式创建目录查看文件目录下的方式上传文件的方式 大数据命令的方…

MySQL怎么排查慢sql语句,排查后一般怎么优化

当排查和优化MySQL中的慢SQL语句时&#xff0c;通常会涉及以下步骤&#xff1a; 识别慢查询&#xff1a; 使用MySQL的慢查询日志&#xff08;slow query log&#xff09;来记录执行时间超过一定阈值的SQL语句。你可以通过修改MySQL配置文件来启用慢查询日志&#xff0c;并设置阈…