AQS:https://www.cnblogs.com/waterystone/p/4920797.html
AQS
AbstractQueuedSynchronizer
AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch...。
AQS维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。
AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。
不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS已经在顶层实现好了。
自定义同步器实现时主要实现以下几种方法:
isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。
tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。
AQS源码解析(1)acquireQueued
https://www.jianshu.com/p/dcbcea767d69
我们来描绘一下排队买票的场景:
当你去买票的时候,首先要看一下窗口有没有人正在受理(tryAcquire),如果没有那么你可以去受理,否则就排在队尾(addWaiter),当然你走到队尾的时候也许受理的人已经好了,所以你要再瞄一眼(acquireQueued中p == head && tryAcquire逻辑)看看能不能去受理,发现还不行那就开始耍手机(acquireQueued中shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt逻辑)(当然如果你不是排队的第一个人,就没有必要去瞄一眼直接刷手机就好了)。