标签:同步锁 success 释放 http unp on() 源码 最大 条件锁
在之前已经有6篇关于AQS源码分析的文章了,关于源码分析的一些问题可以去看看我之前的文章,文章连接可以在文末查看。这一篇文章主要是对AQS的一些总结,或者说是面经。
AQS 全称是AbstractQueuedSynchronizer,在java.util.concurrent.locks
包下面,是一个抽象的可以实现阻塞线程、排队控制、唤醒线程等操作的同步器基础框架类,AQS 可以实现排它锁、共享锁、条件锁、计数器等相关功能。
AQS 继承的父类AbstractOwnableSynchronizer,该类仅一个属性用于记录当前持有锁的线程,提供get/set方法。
state 字段是一个非常重要的字段,可以基于state字段的值定义出不同的同步锁功能,比如:
AQS 里面有两个队列,我称为同步队列和条件队列。条件队列主要是实现条件锁时用到的队列,同步队列就是维护唤醒线程的队列。
await()
的时候会释放锁,然后线程会加入到条件队列,调用signal()
唤醒的时候会把条件队列中的线程节点移动到同步队列中,等待再次获得锁AQS 提供了 5 个可以自定义实现功能的API方法,基于这些方法,则可以实现不同类型的锁功能。
下面的这些模版方法,都用到了上面可以重写的API方法。
基于tryAcquire
API提供的模版方法
获得一个排它锁,直到成功获得锁
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
获得一个排它锁,可被中断
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
获得一个排它锁,可超时或中断
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}
其中tryAcquire(arg)
方法是需要自己实现的方法
基于tryAcquireShared API提供的模版方法
获得一个共享锁,直到成功获得锁
public final void acquireShared(int arg) {
if (tryAcquireShared(arg) < 0)
doAcquireShared(arg);
}
其中tryAcquireShared(arg)
方法是需要自己实现的方法
获得一个共享锁,可被中断
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
获得一个共享锁,支持超时或中断
public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquireShared(arg) >= 0 ||
doAcquireSharedNanos(arg, nanosTimeout);
}
释放一个排它锁
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
其中tryRelease(arg)
方法是需要自己实现的方法
释放一个共享锁
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
其中tryReleaseShared(arg)
方法是需要自己实现的方法
AQS 定义了5个队列中节点状态:
还有一个与AQS非常相似的类——AbstractQueuedLongSynchronizer,从命名上来看,多了一个Long,从源码上来看,他们两个有完全相同的结构、属性和方法,唯一不同之处就在于所有与状态相关的参数和结果都定于为long类型,而不是int类型,当需要创建64位状态的同步器(例如多级锁和屏障)时,AbstractQueuedLongSynchronizer类可能很有用。
AbstractQueuedSynchronizer(AQS) 总结篇
标签:同步锁 success 释放 http unp on() 源码 最大 条件锁
原文地址:https://www.cnblogs.com/admol/p/14023559.html