4-24-aqs抽象的队列同步器

文章目录
  1. 1. aqs抽象的队列同步器
    1. 1.1. state和fifo等待队列
      1. 1.1.1. state 的访问方式有三种
    2. 1.2. 资源共享方式
      1. 1.2.1. 1.独占reentrantLock
      2. 1.2.2. 2.共享semaphore/countDownlatch
      3. 1.2.3. 3. 独占和共享reentrantReadWriteLock
    3. 1.3. 自定义
    4. 1.4. 同步器实现是abs核心(state资源状态计数)

aqs抽象的队列同步器

AQS 定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch

state和fifo等待队列

image-20210717151713814

它维护了一个 volatile int state(代表共享资源)和一个 FIFO 线程等待队列(多线程争用资源被阻塞时会进入此队列)。这里 volatile 是核心关键词,具体 volatile 的语义,在此不述。

state 的访问方式有三种

getState()

setState()

compareAndSetState()

资源共享方式

1.独占reentrantLock

Exclusive(独占,只有一个线程能执行,如 ReentrantLock)

2.共享semaphore/countDownlatch

Share(共享,多个线程可同时执行,如 Semaphore/CountDownLatch)。

3. 独占和共享reentrantReadWriteLock

自定义

  1. 独占模式下只用实现 tryAcquire-tryRelease
  2. 共享模式下只用实现tryAcquireShared-tryReleaseShared。
  3. 如果都定义成abstract,那么每个模式也要去实现另一模式下的接口。不同的自定义同步器争用共享资源的方式也不同。
  4. 自定义同步器在实现时只需要实现共享资源 state 的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS 已经在顶层实现好了。

同步器实现是abs核心(state资源状态计数)

以 CountDownLatch 以例,任务分为 N 个子线程去执行,state 也初始化为 N(注意 N 要与线程个数一致)。这 N 个子线程是并行执行的,每个子线程执行完后 countDown()一次,state会 CAS 减 1。等到所有子线程都执行完后(即 state=0),会 unpark()主调用线程,然后主调用线程就会从 await()函数返回,继续后余动作。