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);
}
}
网友评论