
AQS全称为AbstractQueuedSynchronizer,翻译过来就是抽象队列同步器。使用AQS能够简单且高效地构造出应用广泛的大量的Synchronizer。不仅ReentrantLock 和 Semaphore是构建于AQS上的,其他的还有ReentrantReadwriteLock, countDownLatch和FutureTask等。
AQS解决了实现一个synchronizer的大量细节,比如等待线程的FIFO队列。单独的Synchronizer可以定义一个灵活的标准,用来描述线程是否应该允许通过,还是需要等待。用AQS构建Synchronizer会有很多好处。不仅仅是它能极大地减少实现过程中消耗的精力,而且你再也不必像没有使用AQS构建synchronizer时那样,去应付多个竞争点了。使用 AQS构建的synchronizer只可能在一个点上发生阻塞,这样降低了上下文切换的开销,并提高了吞吐量。AQS的设计充分考虑了可伸缩性,所有 java.util. concurrent中构建于AQS 的 synchronizer都会从中获益。
AQS原理:AQS的核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即把暂时获取不到锁的线程加入到队列中。
CLH(Craig,Landin,and Hagersten)队列(FIFO)是一个虚拟的双向队列,虚拟的双向队列即不存在队列实例,仅存在节点之间的关联关系。AQS是将每一条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node),来实现锁的分配。
AQS有以下几个特点:
AQS就是基于CLH队列,用volatile修饰共享变量state,线程通过CAS去改变状态符,成功则获取锁成功,失败则进入等待队列,等待被唤醒。
有关CLH对象的详细原理如下:(1条消息) AQS的前菜—详解CLH队列锁_fyygree的博客-CSDN博客_clh队列锁