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

参考资源:

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. do_bootrk

    1. LMB (logical memory blocks) lmb为uboot下的一种内存管理机制,用于管理镜像的内存.lmb所记录的内存信息最终会传递给kernel.在/include/lmb.h ...

  2. delphi 演示数据路径

    链接里默认的--------------------------- Error --------------------------- I/O error for file "C:\Prog ...

  3. js批量上传文件

    html代码: <input type="file" id='upload' name="upload" multiple="multiple& ...

  4. 数据库编程测试机试 QQ

    创建QQ数据库 #创建数据库 CREATE DATABASE QQ #创建表名 并且添加列 DROP TABLE IF EXISTS `dbo.BaseInfo`; CREATE TABLE `stu ...

  5. 深入理解Connector

    上一篇主要是从各个容器的生命周期的角度讲了一下整个tomcat的运行流程,说明了各个容器之间的调用关系.但并没有太过详细的说明每一个组件并区分他们. 下面从功能的角度上详细的分析一下connector ...

  6. java去除字符串的空格,换行符,水平制表符,回车

    final private String stringTrimAll(final String input) { if (null == input) return ""; // ...

  7. 数位DP详解

    算法使用范围 在一个区间里面求有多少个满足题目所给的约束条件的数,约束条件必须与数自身的属性有关 下面用kuangbin数位dp的题来介绍 例题  不要62 题意:在一个区间里面求出有多少个不含4和6 ...

  8. AMR11A - Magic Grid

    Thanks a lot for helping Harry Potter in finding the Sorcerer's Stone of Immortality in October. Did ...

  9. shell脚本实例-for实现批量主机的探测

    #!/usr/bin/bash >ip.txt for i in {2..254} do { ip=192.168.234.$i ping -c1 -W1 $ip &>/dev/n ...

  10. ksort 函数

    foreach ($modules AS $key => $value){ ksort($modules[$key]);}ksort($modules); strpos(','.$_SESSIO ...