CAS和AQS一文搞懂
Posted JF Coder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CAS和AQS一文搞懂相关的知识,希望对你有一定的参考价值。
JAVA多线程,面试官喜欢问的东西
一些概念的东西
原子性就是指该操作是不可再分的。不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作。简而言之,在整个操作过程中不会被线程调度器中断的操作,都可认为是原子性。比如 a = 1;
非原子性:也就是整个过程中会出现线程调度器中断操作的现象
类似"a ++"这样的操作不具有原子性,因为它可能要经过以下两个步骤:(1)取出 a 的值
(2)计算 a+1
如果有两个线程t1,t2在进行这样的操作。t1在第一步做完之后还没来得及加1操作就被线程调度器中断了,于是t2开始执行,t2执行完毕后t1开始执行第二步(此时t1中a的值可能还是旧值,不是一定的,只有线程t2中a的值没有及时更新到t1中才会出现)。这个时候就出现了错误,t2的操作相当于被忽略了
JAVA的线程调度—抢占式调度(优先级)
CAS—(Compare And Swap)比较并交换
采用乐观锁思想—总是认为自己可以完成操作
在多个线程操作一个变量时,只有一个线程会成功更新,其他失败,失败线程允许重试
CAS自旋等待
用锁或
synchronized
关键字可以实现原子操作,那么为什么还要用 CAS 呢,因为加锁或使用 synchronized 关键字带来的性能损耗较大,而用 CAS 可以实现乐观锁,它实际上是直接利用了 CPU 层面的指令,所以性能很高。那么CAS 是怎么样实现自旋锁,CAS 利用 CPU 指令保证了操作的原子性,以达到锁的效果,至于自旋,一般是用一个无限循环实现。这样一来,一个无限循环中,执行一个 CAS 操作,当操作成功,返回 true 时,循环结束;当返回 false 时,接着执行循环,继续尝试 CAS 操作,直到返回 true。
进入CAS源码看
import java.util.concurrent.atomic.AtomicInteger;
以原子方式将值设置为给定的更新值(update
),如果当前值等于期望值(expect
)。 返回ture,更新变量的值,实际值不等于期望值返回false,线程什么都不做,CAS返回当前变量值;
public final boolean compareAndSet(int expect, int update)
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
进去unsafe.compareAndSwapInt(this, valueOffset, expect, update);
它是个 native
方法,用 c++ 实现,有兴趣的可以去看看JDK源代码中safe.cpp文件,所以CAS直接跟操作系统进行操作的;
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
CAS产生的ABA问题
什么是ABA?
上面我可以知道,CAS算法实现有一个重要的前提:需要取出内存中某一时刻的数据,然后在下一时刻进行比较,替换,在这个时间差,数据可能已经发生变化,这就导致了ABA问题;
解决方法:部分是通过加版本号(version)来解决,
AQS是一个抽象的队列同步器
AQS维护了一个volatile语义(支持多线程下的可见性)的共享资源变量state和一个FIFO线程等待队列(多线程竞争state被阻塞时会进入此队列)。java.util.concurrent.locks.AbstractQueuedSynchronizer
抽象类,简称 AQS
AQS共享资源的方式:独占式和共享式
AQS默认提供了独占式和共享式两种模式,JDK对应的实现有
ReentrantLock
和ReentrantReadWriteLock
独占式:只有一个线程能执行,具体的JAVA实现有ReentrantLock
共享式:多个线程同时执行
AQS 是基于 volitale 和 CAS 实现的,其中 AQS 中维护一个 valitale 类型的变量 state
来做一个可重入锁的重入次数,加锁和释放锁也是围绕这个变量来进行的。
以上是关于CAS和AQS一文搞懂的主要内容,如果未能解决你的问题,请参考以下文章
面试官最喜欢问的CAS还不会?怎么和他吹牛?!一文带你搞懂CAS
一文彻底搞懂ReentrantLock原理基于AQS的公平锁+非公平锁