拆解

AQS全称 AbstractQueuedSynchronizer , 对于它的理解不是很好说明,如果强行进入,可能基础跟我一样比较差的同学就头晕眼花了。

这里把AQS拆解氛围三块来进行理解。分别是 A Q S

  • A: Abstract 抽象
  • Q: Queued
  • S: Synchronizer

一一击破

Abstract

首先 AQS 本身并不是一个具体的工具🔧,而是一个抽象的实现,实现了API层面的 acquired release 等等操作。而具体如何运行去变更资源,是 共享 还是 独占 ,AQS本身并不关心。而JUC下边实现的工具则有以下几个

  • ReentrantLock
    • CyclicBarrier
  • ReentrantReadWriteLock
  • Semaphore
  • CountDownLatch
  • 线程池Worker
  • 等等

    Queued

开始是抽象,接下里的就是数据结构。如果我们要做并发控制,最简单的方式是就是判断当前资源是否被锁住了,如果没有就我锁住然后执行业务操作,然后已经被别人锁住了,那就直接返回

  • 被其他线程锁住
    • 直接return
  • 资源空闲
    • 我锁住,处理业务逻辑

这种的好处就是实现非常简单,但是简单带来的后果就是粒度太粗了,并发根本上不去,绝大部分请求都是无效请求。作为Java的支撑位,JDK的实现当然不能这么做。

那么在资源被其他线程锁住以后,可以将后续的竞争者放入某一个数据结构中,然后等资源空闲后,大家再去竞争。

这里的竞争是采取自旋进行的,那么能一直自旋么,当然是不行的,白白浪费CPU资源而已,所以获取不到资源锁的线程会进入自我阻塞 LockSupport

Synchronizer

Synchronizer是同步,代表了对资源的一个操作,+1和-1,占用和释放,而在AQS里边则使用一个 **volatile** state 的变量来进行申明和使用,代表的是资源的同步操作,核心就是下边两个方法

  • acquired
  • release

其中有基于这两个引申了更多的方法,例如tryAcquired等等。

Synchronizer 都是和 Queued 一起协同工作的

小结

将AQS拆分开来进行理解,从 Abstract QueuedSynchronizer 进行了一个小的总结,但是不涉及具体的实现,例如Queue的思路等等

关于AQS的分析网上已经有很多很多的大佬写过了,都还写的超nice。