> 参考: [JAVA并发编程: CAS和AQS](https://blog.csdn.net/u010862794/article/details/72892300)
> 整理自 阿里一面总结
## CAS
Compare And Swap,即比较并交换。是解决多线程并行情况下使用锁造成性能损耗的一种机制,属于一种乐观锁。
CAS操作包含三个操作数——内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。
无论哪种情况,它都会在CAS指令之前返回该位置的值。CAS有效地说明了“我认为位置V应该包含值A;如果包含该值,则将B放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。
## AQS
Abstract Queued Synchronizer,抽象队列式同步器,是JDK下提供的一套用于实现基于FIFO等待队列的阻塞锁和相关的同步器的一个同步框架。
> 参考: [AQS深入理解与实战----基于JDK1.8](https://www.cnblogs.com/awakedreaming/p/9510021.html)
想弄懂AQS,先要弄懂“同步器”的概念:
同步器是一种抽象数据类型,在该类型的内部,维护了以下内容:
1. 一个状态变量,该变量的不同取值可以表征不同的同步状态语义(例如表示一个锁已经被线程持有了还是没有任何线程持有)
2. 能够更新和检查该状态变量值的操作(方法)集合
3. 至少有一个方法——当同步状态的值需要时可调用该方法阻塞来修改该状态的线程;或当其他的线程修改了同步状态值,可允许调用该方法唤醒其他阻塞线程
总结来说,就是:同步器中包含一个**可表征同步状态的变量**,**可操作该变量的方法集**,**以及可阻塞或唤醒其他来修改该状态的线程的方法集**。
“抽象”是说该类是一个抽象类,“队列式同步器”是说AQS使用队列来管理多个抢占资源的线程。
AQS在其内部实现了上面所说的同步器的三要素,而且它会把抢占资源失败的线程放入自己内部的一个队列当中维护起来,在这个队列内部的线程会排队等待获取线程。
当多个线程同时调用它的lock()方法获取锁时,它们的本质操作其实就是将该锁实例的同步状态变量的值由0修改为1。第1个抢到这个操作执行的线程就成功获取了锁,后续执行操作的线程就会看到状态变量的值已经为1了,即表明该锁已经被其他线程获取,它们抢占锁失败了。这些抢占锁失败的线程会被AQS放入到一个队列里面去维护起来。当然,实际的情况肯定要稍微复杂些,但本质上是这个道理。
【学习】AQS和CAS