AQS源码解析(6)acquireInterruptibly

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);
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容