Java AQS锁中,acquireQueued方法中什么异常会导致进入的cancelAcquire()方法?

sawi 2019-10-18 03:59:17
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);
}
}
...全文
663 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复 1
线程park阻塞时,这时线程被中断,会抛异常,这个时候就进入finally中
i0bot 2021-02-03
  • 打赏
  • 举报
回复
tryAcquire子类实现会抛出异常.表示AQS的status值溢出了,或者超出最大值了.

lemon0411 2020-03-20
  • 打赏
  • 举报
回复
park状态,或者正常执行状态,调用interrupt() 都不会导致InterruptedException ,所以这里不会是处理 InterruptedException 异常
liuy518329 2020-03-05
  • 打赏
  • 举报
回复 1
1.tryAcquire()抛出异常。 对于AQS来说tryAcquire()是抽象方法,具体实现在子类;在AQS的acquireQueued()方法中调用子类实现的tryAcquire()有可能会抛出一次样;抛出异常后获取锁失败需要cancelAcquire; 2.线程抛出 InterruptedException 异常;
yan_xiao_liu 2020-02-03
  • 打赏
  • 举报
回复
这个异常在获取当前节点的前继节点,你点进获取前继节点的代码,你会发现:我估计这个是处理前继节点为空的时候进行的处理,也就是同步队列只剩下了一个节点的时候,具体的是不是处理仅有一个的,等我想想把,不过,我估计大概率是这样的 if (p == null) throw new NullPointerException();
A天道酬勤 2019-12-25
  • 打赏
  • 举报
回复
如果出现异常或者出现中断,就会执行finally的取消线程的请求操作
zhangqiannh 2019-12-06
  • 打赏
  • 举报
回复
有答案了么,这个我也不太明白
sawi 2019-10-23
  • 打赏
  • 举报
回复
引用 3 楼 ml_dark 的回复:
这里没有捕获异常的,无论有无异常,都会执行finally方法,finally代码始终是会执行的,跟有无异常无关
可能我的意思没有表达清楚,亦或是您没明白我的意思。 初始化 boolean failed = true; 1、finally势必是会执行的,这是一定的,但是 finally代码中的cancelAcquire(node)方法执不执行就不一定了,我的问题表达的是finally方法中的cancelAcquire由于什么情况执行的? 2、正常流程下,for循环是一个死循环,当且仅当程序获取到锁后,此时failed = false;一定不会执行cancelAcquire方法 3、既然是for死循环,那么如果程序始终没有获取到锁,而且又需要执行cancelAcquire方法,那么肯定是抛出异常了,即使没有异常捕获,但是异常抛出了异常,线程导致中止前,势必执行cancelAcquire方法(此时failed = true),那么就需要判断try块中那些方法会抛出异常!(从代码角度看只有node.predecessor()方法和tryAcquire(arg)方法会主动抛出异常) 个人在学习重入锁发现,实现类会主动在tryAcquire方法抛出throw new Error("Maximum lock count exceeded"),溢出资源上限。 在node.predecessor()中存在throw new NullPointerException();,当根据doc文档介绍:The null check could be elided, but is present to help the VM.表示此异常无代码层面的意义。
ml_dark 2019-10-23
  • 打赏
  • 举报
回复
这里没有捕获异常的,无论有无异常,都会执行finally方法,finally代码始终是会执行的,跟有无异常无关
sawi 2019-10-22
  • 打赏
  • 举报
回复
引用 1 楼 ml_dark 的回复:
当获取到锁的时候就会进入finally方法,try方法块是个死循环,AQS获取锁的方式死循环一直到获取锁为止。
我的意思时进入cancelAcquire中,什么异常会导致进入cancelAcquire?当获取到锁的时候,failed = false,无法进入cancelAcquire,看代码只有异常才会进入cancelAcquire,什么异常会导致进入cancelAcquire?
ml_dark 2019-10-21
  • 打赏
  • 举报
回复
当获取到锁的时候就会进入finally方法,try方法块是个死循环,AQS获取锁的方式死循环一直到获取锁为止。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧