java - AQS 如何处理中断
问题描述
当一个节点排队等待锁时,另一个线程中断了他,他会旋转一次然后取消中断并重新挂起自己,就像它从未中断过一样。
按照我的理解,他应该取消锁获取,但现在看来不是这样。当他之前的节点释放锁时,他仍然会像从未中断过一样抢锁,谁能告诉我为什么?版本是JDK8
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
return Thread.interrupted();
}
解决方案
在您的代码中,线程for(;;)
只能以一种方式离开该无限循环 - 在它满足条件之后if(p == head && tryAcquire(arg))
- 因为它是唯一的return
语句,所以您也没有任何中断。
但是,您说“未获得锁定”,这意味着线程必须继续执行此 for 循环中的内容,这意味着执行第二个 if(再次挂起线程)。
当你有一个构造
try {
// some code
}finally{
// finally execution
}
块中的代码finally
只有在执行离开try
块后才会执行(正常或由于异常)。
推荐阅读
- python - Python 记录器抛出 IOError:[Errno 22] 无效参数
- sql - ORA-00913 的嵌套选择错误:值太多
- scripting - 如何在 tcl 文件中添加微秒延迟?
- python - 预期 conv1d_1_input 的形状为 (15, 512) 但得到的数组形状为 (4, 512)
- uber-api - 使用 Uber 的用户访问令牌会减少通过特权范围对其 API 的调用吗?
- javascript - 如何调试我的鼠标事件处理程序
- networking - ntc-ansible 模块的 SSH 连接问题
- spring-boot - Spring Boot + Mustache:仅在用户通过身份验证时才呈现 html
- case - 案例语句重复行 - teradata
- javascript - 如何在javascript中延迟按钮的输出