Java 并发编程之 AQS ReentrantLock 可中断锁源码解析

Java juc AQS 大约 1338 字

部分源码

java.util.concurrent.locks.ReentrantLock#lockInterruptibly

public void lockInterruptibly() throws InterruptedException {
    sync.acquireInterruptibly(1);
}

java.util.concurrent.locks.AbstractQueuedSynchronizer

public final void acquireInterruptibly(int arg)
        throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    if (!tryAcquire(arg))
        doAcquireInterruptibly(arg);
}

private void doAcquireInterruptibly(int arg)
    throws InterruptedException {
    final Node node = addWaiter(Node.EXCLUSIVE);
    try {
        for (;;) {
            final Node p = node.predecessor();
            if (p == head && tryAcquire(arg)) {
                setHead(node);
                p.next = null; // help GC
                return;
            }
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                throw new InterruptedException();
        }
    } catch (Throwable t) {
        cancelAcquire(node);
        throw t;
    }
}

private final boolean parkAndCheckInterrupt() {
    LockSupport.park(this);
    return Thread.interrupted();
}

可中断锁如果一开始tryAcquire抢得锁了就继续执行锁内的代码。

如果没有抢得锁,在LockSupport.park()处停止,当线程被调用了interrupte()方法后,LockSupport.park()恢复执行。并且抛出了异常。

抛出异常后又在catch中捕获了Throwable异常,处理取消节点的逻辑,最后再抛出去。

阅读 34 · 发布于 2021-10-06

————        END        ————

扫描下方二维码关注公众号和小程序↓↓↓

扫描二维码关注我
昵称:
随便看看 换一批