聊聊 CAS
哥有故事,你有酒,长夜漫漫,听我给你说。
参考资源:
https://blog.csdn.net/hsuxu/article/details/9467651
1.概述
CAS,compare and swap ,“比较交换”的意思。它是一种并发状态下的,比较交换的策略。
想必,我们一定听说过乐观锁的概念,并发中乐观锁的核心概念就是应用了CAS。它包含了三个值:内存值,预期值和更新值。当内存值和预期值相等时,就会使用更新值将原来的数据(预期值)进行更新;如果不相等,则什么都不做。
2.例子
举个经典的例子,帮助大家理解。(伪代码)
public class AtomicInt {
private volatile int value;
public final int get() {
return value;
}
publicfinal int getAndIncrement() {
// 下面的for的无限循环,就是经典的CAS自旋(Compare and swap)
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
public final boolean compareAndSet(int expect, int update) {
unsafe.compareAndSwapInt方法(方法内部,使用JNI调用C的代码);
}
}
3.凡事问个为什么.
为什么要比较?为什么要用CAS的自旋?直接设值不行吗?它有什么优点缺点?
例如,i++ 这个简单的操作不是一步完成的,而是分了三步。第一步,取值,第二步加一,第三部更新值。
假设有A,B两个线程同时操作i++这个处理,那么,当线程A完成上述第二步的时候,线程B已经将I的值更新(第三步)做完了。这样就会导致值发生异常,就是所谓的线程不安全。
所以,利用了乐观锁的思想采用了自旋的方式,每一次,就会先取得加一后的值,再将旧的值和内存中的值进行比较,如果相等,则说明,没有被别的线程动过,因此可以正常更新;如果不相等,则说明值已经被更新了,放弃本次的操作,从头再来,再重新取值,加一,更新。
CAS自旋(乐观锁)避免了悲观锁独占的现象,同时提高了并发的性能。但是,它也是有缺点的。(第三点参考了其他文章)
①乐观锁只能保证一个变量的的原子操作,多个变量的话,就没有办法了。
②长时间自旋,导致CPU消耗过大。
③ABA问题。CAS的核心思想是通过比对内存值与预期值是否一样而判断内存值是否被改过,但是,假如内存值原来是A,后来被一条线程改为B,最后又被改成了A,则CAS认为此内存值并没有发生改变,但实际上,被其他线程改过。这种情况对依赖过程值的情景的运算结果影响很大。解决的思路是引入版本号,每次变量更新都把版本号加一。
4. 原子类Atomic
现在习惯多去查api文档(这是个好的习惯)。在JUC的atomic包下有如下几个类:
AtomicBoolean
AtomicInteger
AtomicLong
AtomicMarkableReference
AtomicReference
它们的原理都是应用了CAS的自旋,这几个类在并发编程中经常用到,它们都是线程安全的类。
就聊这么多,祝君好梦!
聊聊 CAS的更多相关文章
- 聊聊CAS - 面试官最喜欢问的并发编程专题
什么是CAS 学习Java并发编程,CAS(Compare And Set)机制都是一个不得不掌握的知识点.除了通过synchronized进行并发控制外,还可以通过CAS的方式控制,大家熟悉的Ree ...
- JAVA并发编程: CAS和AQS
版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/u010862794/article/details/72892300 说起JAVA并发编程,就不得不聊 ...
- 聊聊 JDK 非阻塞队列源码(CAS实现)
正如上篇文章聊聊 JDK 阻塞队列源码(ReentrantLock实现)所说,队列在我们现实生活中队列随处可见,最经典的就是去银行办理业务,超市买东西排队等.今天楼主要讲的就是JDK中安全队列的另一种 ...
- 聊聊并发(六)——CAS算法
一.原子类 1.CAS算法 强烈建议读者看这篇之前,先看这篇 初识JUC 的前两节,对原子性,原子变量,内存可见性有一个初步认识. CAS(Compare and Swap)是一种硬件对并发的支持,针 ...
- 聊聊单点登录(SSO)中的CAS认证
SSO介绍 背景 随着企业的发展,一个大型系统里可能包含 n 多子系统, 用户在操作不同的系统时,需要多次登录,很麻烦,我们需要一种全新的登录方式来实现多系统应用群的登录,这就是单点登录. web 系 ...
- 并发系列2-大白话聊聊Java并发面试问题之Java 8如何优化CAS性能?【石杉的架构笔记】
- paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)
paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1 锁的缺点 2 CAS(Compare ...
- 聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁
上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和基本的方法,显示了怎样 ...
- 聊聊高并发(二十)解析java.util.concurrent各个组件(二) 12个原子变量相关类
这篇说说java.util.concurrent.atomic包里的类,总共12个.网上有非常多文章解析这几个类.这里挑些重点说说. watermark/2/text/aHR0cDovL2Jsb2cu ...
随机推荐
- shell script auto generate the relevant header information
first : add follow context in /etc/vim/vimrc set ignorecaseset cursorlineset autoindentautocmd Buf ...
- 尚学堂java 答案解析 第四章
本答案为本人个人编辑,仅供参考,如果读者发现,请私信本人或在下方评论,提醒本人修改 一.选择题 1.BD 解析:B:类必须有构造方法,若程序未写,这系统自动调用系统构造方法. D:super()会调用 ...
- ssd物体检测模型训练和测试总结
参考网址:github:https://github.com/naisy/realtime_object_detection 2018.10.16ssd物体检测总结:切记粗略地看一遍备注就开始训练模型 ...
- unity中自制模拟第一人称视角
public float sensitivityX = 5f; public float sensitivityY = 5f; public float sensitivetyKeyBoard = 0 ...
- oracle日志相关的表
SELECT * FROM all_objects t where object_name like '%EN_CONCAT_IM%';DBA_HIST_SQLTEXTDBA_HIST_SQLSTA ...
- jmeter源码导入eclipse并执行
由于JMeter纯Java开发,界面也是基于Swing或AWT搞出来的,所以想更深层次的去了解这款工具或对于想了解JMeter插件开发或二次开发的童鞋们来说,读读JMeter的源码估计是必不可少的,所 ...
- Java语法基础学习DayEight
一.异常处理 1.结构 java.lang.Object |-----java.lang.Throwable |-----java.lang.Error:错误,java程序对此无能为力,不显式处理 | ...
- 2019-03-08-day007-深浅拷贝
01 昨日内容回顾 is 两者之间的id是否相同 == 两边的数值是否相等 id 获取该对象的内存地址 代码块: 一个文件,交互式命令行:一行是个一个代码块. 同一代码块下: 字符串的缓存机制,驻留机 ...
- Python 验证进程之间是空间隔离的
from multiprocessing import Process num = 100 def f1(): global num num = 3 print("子进程中的num" ...
- tomcat自动缓存的几种解决方式
第一种方法:打开一个项目,这里我打开的Mail项目,然后点击Myeclipse菜单栏中的project-选择clean: 选择要clean的项目,确定即可不用进入tomcat服务器直接清理缓存. 上面 ...