关于中断
对于响应中断我们可以发现AQS 代码
1 开始时测试判断线程是否中断
if (Thread.interrupted())
/** 抛出异常 **/
throw new InterruptedException();
2 当线程阻塞后,在次测试判断线程是否中断而唤醒,如果唤醒则抛出异常
private final boolean parkAndCheckInterrupt() {
/** 阻塞当前线程(可响应中断)**/
LockSupport.park(this);
/** 如果线程是中断从阻塞唤醒返回true **/
return Thread.interrupted();
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
3 需要注意Thread.interrupted() 是可以重置中断标志的(如果线程已经为true重新设置为false)。
关于业务流程
AQS 内部使用了大量的自旋处理业务。
boolean failed = true;
try {
for (;;) {
逻辑校验1
逻辑校验1
业务处理设置标记1
业务处理设置标志2
if(判断标志1){
正常退出
}
if(判断标志2){
超时退出
}
} finally {
/** 发生异常,将当前节点等待状态设置为取消**/
if (failed)
cancelAcquire(node);
}
}
网友评论