一,AQS详解
参考博文https://www.cnblogs.com/waterystone/p/4920797.html
首先,AQS维护了一个共享变量state,和一个FIFO队列。state的访问方式有三种:
getState()
setState()
compareAndSetState()
AQS有独占和共享这两种资源共享方式。
自定义同步器只需要实现共享资源的state的获取与释放即可。需要实现如下方法:
isHeldExclusively():该线程是否正在独占资源
tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。
源码详解!!!!!!
1,acquire方法
此方法是独占模式下线程获取state的顶层入口。源码如下
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
用到的函数如下
1,tryAcquire :尝试去获取state,如果成功则直接返回
2,addWaiter将该线程加入等待队列的尾部,并标记为独占模式
3,acquireQueued使线程在等待队列中获取资源,一直到获取到资源才返回。如果在整个等待过程中被中断过,则返回true,否则返回false。
4,selfInterrupt:进行自我中断
下面我们开始逐个方法分析
1,,tryAcquire 源码如下
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
是不是有点蒙蔽,为啥就单单只是抛了个异常。AQS毕竟只是一个框架,具体的实现还要靠自定义的同步器自己去设计。
这里我们简要分析下lock中非公平锁的tryAcquire实现,源码如下
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
这段代码还是比较容易理解的。。。我就不多加赘述了。。。
2,addWaiter
源码如下
private Node ad