美文网首页
AQS源码解析(6)acquireInterruptibly

AQS源码解析(6)acquireInterruptibly

作者: 三斤牛肉 | 来源:发表于2021-01-08 15:19 被阅读0次

reentrantlock中有lockInterruptibly函数,表示可响应中断,之前讲的lock是不会响应中断的:

public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt(); //这里会去调用interrupt,但是线程还是会继续执行完
}

lockInterruptibly核心函数:

public final void acquireInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())//如果线程在获取锁之前就被打断,则异常
            throw new InterruptedException();
        if (!tryAcquire(arg))//如果尝试获取锁成功表示没有线程获取锁,不需要排队,则继续执行,就跟new thread一样,改怎么打断就怎么打断
            doAcquireInterruptibly(arg);
    }

doAcquireInterruptibly:

//整段代码和acquireQueued差不多的,唯一的区别在异常
private void doAcquireInterruptibly(int arg)
        throws InterruptedException {
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())//看这里如果parkAndCheckInterrupt返回的是true,表示线程唤醒前曾今被调用Interrupt()过
                    throw new InterruptedException();//则抛出异常,这里就是响应打断,而之前的[acquireQueued](https://www.jianshu.com/p/dcbcea767d69)则会返回parkAndCheckInterrupt的返回值,最终只是保证Interrupt值一致
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

相关文章

网友评论

      本文标题:AQS源码解析(6)acquireInterruptibly

      本文链接:https://www.haomeiwen.com/subject/fihooktx.html