前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CAS机制是什么?

CAS机制是什么?

作者头像
写一点笔记
发布2020-08-25 11:34:47
1.5K0
发布2020-08-25 11:34:47
举报
文章被收录于专栏:程序员备忘录程序员备忘录

因为多核CPU的存在,总是需要保障程序高性能的利用计算机的CPU资源,并要保障计算结果与预期的一致。因此常用的方式就是加锁方式。就是占用->占用结束->释放的过程,在此过程中不允许其他线程来操作已经占用的计算机资源。在单核CPU系统中,可直接通过锁住数据总线的方式达到目标。但对于多核CPU来说,其效率就太糟糕了。在多核CPU中是怎么做呐?其做法的本质还是加锁。其中CAS就是一种指令级的加锁。

  1. 什么是CAS?

CAS是compare and swap的缩写,就是比较并替换的意思。

2. CAS(比较并替换)如何保障数据一致性的?

我们设想一下,假如有2个线程。同时要操作计算机内存中的数据X=10,并将X进行加1操作。

比如线程I获取X,线程II获取X,线程II进行加1操作。此时线程I获取的X的值为10,加1之后变为11,而线程II已经将X的值变为11,因此两个线程对X的加一操作并没有达到理想中的12,而是变成了11。所以数据的一致性就得不到保障。那么面对这种情况,该如何保障数据的最终一致性?CAS的处理方式是在给X设置值得之前获取X的值,然后比较在设置值得的时候的时间段内获取到的值是否与内存中的值相同,如果相同的话,就表示X的值没有被其他线程修改,如果内存中的值与之前获取到的值不一致就表示该值已经被其他线程修改,所以该线程就抛弃之前获取到的内存中的值,并将新值作为标志。如此循环,直到计算前后从内存中获取的数据没有变化,就将其计算的结果放置到内存中。所以说CAS其实就是通过比较计算前后,所操作的数据是否发生变化来进行高并发情况下数据的一致性的。如果没有发生变化就说明当前线程的操作是安全的,否则就轮循直到所操作的数据不再变化再进行计算和赋值操作。

在此可能有人会说,那么在比较确认数据没有被其他线程修改之后设置值得时候被其他线程修改了数据怎么办?这里要注意一下CAS最终设置值得时候采用的计算机指令是原子性的,也就是说会一步走到结束。

3.CAS机制的优势和劣势是什么?

轮循导致的CPU消耗

上边说到如果所操作的数据在当下线程操作的空隙已经发生了变化,就需要不断的去轮询,直到其不再发生变化了之后才进行下一步操作。但是轮询非常消耗CPU。

只能保障数据的原子性,无法保障代码块的原子性

当多个线程操作相同的数据时,使用CAS策略能够保证该数据的原子性,但是无法保障代码块的原子性。要想实现代码块中的数据不被其他线程修改(不与预期值发生偏差),则必须使用synchronized来进行代码块级别锁了。

ABA问题

当线程I修改了X,但是线程I又将X修改为原来的值,所以线程II使用CAS策略去修改X的值时发现X并没有被修改并进行计算的过程。

线程I 获取X=10----->对X+1=11----->对X-1=10

线程II 获取X=10----------------------------------->X+1=11

时间线 t1-----------------t2------------------t3--------------t4--->

ABA问题的根源就是无法确认数据修改者的身份,因此可以通过过添加版本号的方式去解决,通过比较值再比较版本号的方式去判断其操作者,直到数据的版本号是操作者颁发的时候才有权利去修改,这样就可以解决ABA的问题。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员备忘录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档