(1)什么是AQS?AQS的底层实现原理是什么?
AQS 是一个锁框架,它定义了锁的实现机制,并开放出扩展的地方,让子类去实现。比如我们在 lock 的时候,AQS 开放出 state 字段,让子类可以根据 state 字段来决定是否能够获得锁,对于获取不到锁的线程 AQS 会自动进行管理,无需子类关心。
底层实现原理:如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制。这个机制 AQS 是基于 CLH 锁实现的。CLH 锁是对自旋锁的一种改进,是一个虚拟的双向队列(虚拟的双向队列,不存在队列实例,仅存在结点之间的关联关系),暂时获取不到锁的线程将被加入到该队列中。AQS 将每条请求共享资源的线程封装成一个 CLH 队列锁的一个结点(Node)来实现锁的分配。在 CLH 队列锁中,一个节点表示一个线程,它保存着线程的引用(thread)、当前节点在队列中的状态(waitStatus)、前驱节点(prev)、后继节点(next)。
(2)了解AQS的资源共享方式吗?
Exclusive独占:只有一个线程能执行,如ReentrantLock
Share共享:多个线程可同时执行,如Semaphore(信号量)/CountDownLatch(倒计时器)/CyclicBarrier(循环栅栏)。
(3)基于AQS的同步工具类(组件)有哪些?
Semaphore(信号量):允许多个线程同时访问某个资源。 synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源。
CountDownLatch(倒计时器):能控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。
CyclicBarrier(循环栅栏):让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。