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

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);
        }
    }

当获取到锁的时候就会进入finally方法,try方法块lrc歌词是个死循环,AQS获取锁的方式死循环一直到获取锁为止。

我的意思时进入cancelAcquire中,什么异常会导致进入cancelAcquire?当获取到锁的时候,failed = false,无法进 入cancelAcquire,看代码只有异常才会进入cancelAcquire,什么异常会导致进入cancelAcquire?

这里没有捕获异常的,无论有无异常,都会执行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();,当根据d

oc文档介 绍:The null check could be elided, but is present to help the VM.表示此异常无代码 层面的意义。
 

有答案了么,这个我也不太明白

如果出现异常或者出现中断,就会执行finally的取消线程的请求操作

这个异常在获取当前节点的前继节点,你点进获取前继节点的代码,你会发现:我估计这个是处理前继节点为空的时候进行的处理,也就是同步队列只剩下了一个节点的时候,具体的是不是处理仅有一个的,等我想想把,不过,我估计大概率是这样的
if (p == null)
                throw new NullPointerException();

发布了79 篇原创文章 · 获赞 2 · 访问量 2274

猜你喜欢

转载自blog.csdn.net/liuji0517/article/details/104669356