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

参考资源:

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. UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  2. bzoj1261

    题解: 看到了树 很明显就是树形dp吗 然后随便yy一下方程就好了 代码: #include<bits/stdc++.h> using namespace std; int n,j; ], ...

  3. JAVA设计模式(二)工厂模式

    在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一 ...

  4. 70 多表查询的分组F 聚合 Q 查询

    聚合查询和分组查询 聚合 aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典.键的名称是聚合值的标识符,值是计算出来的聚合值.键的名称是按照字段和聚合函 ...

  5. 2019-03-26-day019-面向对象耦合与组合

    作业 #对象的耦合 class Circle: def __init__(self,r): self.r = r def area(self): return 3.14*self.r**2 def p ...

  6. Java学习笔记10(面对对象:构造方法)

    在开发中经常需要在创建初始化对象时候明确对象的属性值, 比如Person对象创建的时候就给Person的属性name,age赋值, 这里就要用到构造方法: 构造方法是类的一种特殊方法,它的特殊性体现在 ...

  7. react native 之 获取键盘高度

    多说不如多撸: /** * Created by shaotingzhou on 2017/2/23. *//** * Sample React Native App * https://github ...

  8. 对于src路径问题,深层理解的实践。且对于输出流write()两个方法的源码阅读。

    根据昨天的总结,可深层理解图片中src的路径.所以今天实现了一个想法.就是路径写入的是Controller,然后自动去本地找. 其实就是将电脑的本地图片 显示出来.通过输出流的方式. 代码如下: @R ...

  9. 机器学习:Kullback-Leibler Divergence (KL 散度)

    今天,我们介绍机器学习里非常常用的一个概念,KL 散度,这是一个用来衡量两个概率分布的相似性的一个度量指标.我们知道,现实世界里的任何观察都可以看成表示成信息和数据,一般来说,我们无法获取数据的总体, ...

  10. npm 包管理器的使用

    1. 权限问题 Warning "root" does not have permission to access the dev dir · Issue #454 · nodej ...