多线程(13) — AQS

AQS是指AbstractQueuedSynchronizer,抽象同步队列。AQS是多个重要接口实现的工具类包括之前讲的Condition,Condition接口由ConditionObject实现,而ConditionObject又是AQS的内部类,所以AQS是实现其功能的重要工具类。
AQS分为独占模式和共享模式,独占模式下其他线程无法获取该线程锁。在共享模式下AQS维护了一个等待资源的FIFO先进先出队列,在线程1资源被释放后,AQS会从头结点开始依次唤醒队列中的线程2等线程2结束后再唤醒后面的从前至后的所有结点,使他们对应的线程恢复执行。直到队列为空。
如果不用AQS那么在唤醒有成千上万条等待线程去竞争锁资源的时候就会发生羊群效应,大量的线程去竞争资源造成资源的剧增和浪费,而且最终也只能有一个线程成功,其余的线程还是要全部返回去等待。AQS的FIFO队列让每个节点只关心前一个结点的状态,只有前一个结点线程释放资源后才轮到自己,大大减少了线程间的竞争。

(相关参考:http://www.importnew.com/9281.html)

AQS支持默认的独占 模式和共享 模式之一,或者二者都支持。处于独占模式下时,其他线程试图获取该锁定将无法取得成功。在共享模式下,多个线程获取某个锁定可能(但不是一定)会获得成功。此类并不“了解”这些不同,除了机械地意识到当在共享模式下成功获取某一锁定时,下一个等待线程(如果存在)也必须确定自己是否可以成功获取该锁定。处于不同模式下的等待[线程]可以共享相同的 FIFO [队列]。通常,实现子类只支持其中一种模式,但两种模式都可以在ReadWriteLock 中发挥作用。

此类通过支持独占模式的子类定义了一个嵌套的 AbstractQueuedSynchronizer.ConditionObject 类,可以将这个类用作 Condition 实现。isHeldExclusively 方法将报告同步对于当前线程是否是独占的;使用当前 getState 值调用 release(int) 方法则可以完全释放此对象;如果给定保存的状态值,那么 acquire(int) 方法可以将此对象最终恢复为它以前获取的状态。没有别的 AbstractQueuedSynchronizer 方法创建这样的条件,因此,如果无法满足此约束,则不要使用它。AbstractQueuedSynchronizer.ConditionObject 的行为当然取决于其同步器实现的语义。

此类为内部[队列]提供了检查、检测和监视方法,还为 condition 对象提供了类似方法。可以根据需要使用用于其同步机制的 AbstractQueuedSynchronizer 将这些方法导出到类中。

(AQS把其他知识点都串联起来的其他参考:http://ifeve.com/abstractqueuedsynchronizer-use/)

你可能感兴趣的:(多线程(13) — AQS)