有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java问题:不释放所有路径上的锁

我有下面提到的代码。我在finally块中释放锁,但sonarqube仍显示“不释放所有路径上的锁”消息。 我试着换锁。isHeldByCurrentThread()以锁定。我被锁定了,但仍然没有运气。我没有在任何其他方法中使用lock。没有关于如何解决声纳问题的线索

class Sample{
    ReentrantLock lock = new ReentrantLock();

    public Response<T> method(Inputs input){

        try{
            // some logic
            lock.lock();

        }catch(Exceptions e){
            // handle exception
        }finally{
            if(lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }
    }
}


共 (1) 个答案

  1. # 1 楼答案

    声纳在这里看到的是,你正在无条件地获取一个锁,然后只在某些条件下释放它。Sonarqube无法判断选择不释放锁的路径的可能性有多大,它只看到这可能发生

    还要注意的是,您用于检查锁的这些方法似乎不适用于此用途。例如ReentrantLock#isHeldByCurrentThread的文档说明:

    this method is typically used for debugging and testing.

    这似乎是一个警告,你应该重新考虑在这里使用它

    看起来这段代码使用这个方法是为了区分在获取锁之前抛出异常的情况和已经获取锁的情况,以便知道是否需要释放锁

    答案不是用什么方法来测试锁,看它是否被获取,而是修复代码,这样就不需要进行测试。添加另一个try块,如下所示:

    class Sample{
        ReentrantLock lock = new ReentrantLock();
    
        public Response<T> method(Inputs input){
    
            try{
                // do whatever needs doing prior to acquiring lock
                lock.lock();
                try {
                    // do whatever needs doing with lock held
                } finally {
                    // release lock on the way out of inner try block
                    lock.unlock();
                }
            } catch (Exception e){
                // handle exception thrown from anywhere within outer or inner try block
            }
        }
    }
    

    这样,如果执行进展到获取锁的程度,它将在退出时被释放。如果在任何地方抛出异常,它将被捕获,锁将被解锁

    TLDR:如果你无条件获得锁,那么你应该无条件释放它