Open wittyResry opened 4 years ago
(1)当一个线程调用acquire(int arg),首先使用tryAcquire(arg)尝试获取独占资源,获取失败则将失败则将当前线程封装为类型为Node.EXCLUSIVE的Node节点后插入到AQS阻塞队列的尾部,并调用LockSupport.park(this)方法挂起自己。
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) {
selfInterrupt();
}
}
(2) 当一个线程调用release(arg),首先使用tryRelease(arg)释放资源,然后调用LockSupport.unpark(thread)方法激活AQS队列里面被阻塞的一个线程(thread)。
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0) {
unparkSuccessor(h);
}
return true;
}
return false;
}
需要注意的是,AQS类并没有提供可用的tryAcquire和tryRelease方法,正如AQS是锁阻塞和同步器的基础框架一样,tryAcquire和tryRelease需要由具体的子类来实现。
一、首先需要了解LockSupport.park和LockSupport.unpark(thread)