聊聊 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 ...
随机推荐
- oo作业总结(二)
概述 和前三次作业相比,这几次作业最大的不同是难度的飞跃.遗憾的是在这难度的变化面前,我自己却没有做好充分的准备,错误的低估了作业难度导致给自己带来了很多不必要麻烦和损失.接下来我将对它们进行说明(度 ...
- OO Summary Ⅱ
[第五次作业——多线程电梯] 类图 度量 协作图 设计分析: 多线程电梯是我第一次接触多线程,因此真的是无(瞎)从(g)下(2)手(写),感觉仿佛只是用一个调度器来调度3部电梯但又总觉得好像哪里不太对 ...
- 【原创】QT简单计算器
代码 //main.cpp #include "calculator_111.h" #include <QtWidgets/QApplication> int main ...
- FFT理解
*连续时间-周期性信号频谱 clc;clear;close all N = input('N= '); T = 0.05; n = 1:N; %原始数据输入 D = 2*pi/(N*T); %计算分 ...
- kbmMW安全第#3 - 基于硬件的随机数#2
在之前的基于硬件的随机数博文中,我介绍了如何使用基于外部硬件的随机数生成器,来生成高质量的随机数. 但是,后来英特尔和AMD的CPU也包含随机值生成器.从2015年6月开始,来自Ivy Bridge的 ...
- 2017第八届蓝桥杯C/C++ B组省赛-购物单
标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折 ...
- 2.22 JS处理富文本
2.22 JS处理富文本 前言 <富文本>这篇解决了富文本上iframe问题,其实没什么特别之处,主要是iframe的切换,本篇讲解通过js的方法处理富文本上iframe的问题一.加 ...
- Android反调试笔记
1)代码执行时间检测 通过取系统时间,检测关键代码执行耗时,检测单步调试,类似函数有:time,gettimeofday,clock_gettime. 也可以直接使用汇编指令RDTSC读取,但测试AR ...
- 数据结构与算法Java描述 队列
package com.cjm.queue; /** * 数据结构与算法Java实现 队列 * * @author 小明 * */ public class Myqueue { private Nod ...
- tarfile — Read and write tar archive files
参考: https://docs.python.org/2/library/tarfile.html http://www.jianshu.com/p/bbad16822eab #解压文件tarfil ...