哥有故事,你有酒,长夜漫漫,听我给你说。

参考资源:

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的更多相关文章

  1. 聊聊CAS - 面试官最喜欢问的并发编程专题

    什么是CAS 学习Java并发编程,CAS(Compare And Set)机制都是一个不得不掌握的知识点.除了通过synchronized进行并发控制外,还可以通过CAS的方式控制,大家熟悉的Ree ...

  2. JAVA并发编程: CAS和AQS

       版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/u010862794/article/details/72892300 说起JAVA并发编程,就不得不聊 ...

  3. 聊聊 JDK 非阻塞队列源码(CAS实现)

    正如上篇文章聊聊 JDK 阻塞队列源码(ReentrantLock实现)所说,队列在我们现实生活中队列随处可见,最经典的就是去银行办理业务,超市买东西排队等.今天楼主要讲的就是JDK中安全队列的另一种 ...

  4. 聊聊并发(六)——CAS算法

    一.原子类 1.CAS算法 强烈建议读者看这篇之前,先看这篇 初识JUC 的前两节,对原子性,原子变量,内存可见性有一个初步认识. CAS(Compare and Swap)是一种硬件对并发的支持,针 ...

  5. 聊聊单点登录(SSO)中的CAS认证

    SSO介绍 背景 随着企业的发展,一个大型系统里可能包含 n 多子系统, 用户在操作不同的系统时,需要多次登录,很麻烦,我们需要一种全新的登录方式来实现多系统应用群的登录,这就是单点登录. web 系 ...

  6. 并发系列2-大白话聊聊Java并发面试问题之Java 8如何优化CAS性能?【石杉的架构笔记】

  7. paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)

    paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1     锁的缺点 2     CAS(Compare ...

  8. 聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁

    上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和基本的方法,显示了怎样 ...

  9. 聊聊高并发(二十)解析java.util.concurrent各个组件(二) 12个原子变量相关类

    这篇说说java.util.concurrent.atomic包里的类,总共12个.网上有非常多文章解析这几个类.这里挑些重点说说. watermark/2/text/aHR0cDovL2Jsb2cu ...

随机推荐

  1. iframe子父页面函数互相调用

    1.iframe子页面调用父页面js函数 子页面调用父页面函数只需要写上window.praent就可以了.比如调用a()函数,就写成: window.parent.a();  子页面取父页面中的标签 ...

  2. jsp标签之jsp:setProperty用法

    参考:http://blog.csdn.net/wanghaishanren/article/details/2047400

  3. xshell提示必须安装最新的更新

    今天大家的xshell基本都出了这个问题 调整时间,调整到比较前的时间,打开xshell即可. 然后工具->选项 把更新去了

  4. 图解中序遍历线索化二叉树,中序线索二叉树遍历,C\C++描述

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  5. Reveal 破解及使用

    Reveal是一款很好的iOS调试应用,这在你的开发中起到了相当大的帮助. 破解包可去http://xclient.info/?_=118ba0724e7a6af91ba29a22ee4131da 下 ...

  6. 十. Python基础(10)--装饰器

    十. Python基础(10)--装饰器 1 ● 装饰器 A decorator is a function that take a function as an argument and retur ...

  7. (C/C++学习笔记) 二十三. 运行时类型识别

    二十三. 运行时类型识别 ● 定义 运行时类型识别(Run-time Type Identification, RTTI) 通过RTTI, 程序能够使用基类的指针或引用来检查(check)这些指针或引 ...

  8. fastIO

    文件系统除了处理正常的IRP 之外,还要处理所谓的FastIo.FastIo是Cache Manager 调用所引发的一种没有irp 的请求.换句话说,除了正常的Dispatch Functions ...

  9. 201621123001 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集 异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出 ...

  10. linux一些命令的介绍

    http://www.runoob.com/linux/linux-command-manual.html 寻找文档操作命令wc -l时,发现一个好的介绍linux操作命令的网站.