1

声纳报告以下问题:

Multithreaded correctness - Method does not release lock on all
exception paths findbugs : UL_UNRELEASED_LOCK_EXCEPTION_PATH
This method acquires a JSR-166 (java.util.concurrent) lock, but does not release it on all exception paths out of the method. In general, the correct idiom for using a JSR-166 lock is:  



Lock l = ...;
l.lock();
try {
    // do something
} finally {
    l.unlock();
}

在此代码段上:

   public synchronized void put(T element) throws PreconditionException {
        Precondition.notNull(element, "Nullobject is not allowed");
        lock.lock();
        try {
            buffer[writeIndex++] = element;
            if (writeIndex >= capacity) {
                writeIndex = 0;
            }
            if (size.get() >= capacity) {
                // buffer is full
                readIndex++;
                lastOverflow.set(System.currentTimeMillis());
                if (readIndex >= capacity) {
                    readIndex = 0;
                }
                return;
            }
            size.incrementAndGet();
        } finally {
            try {
                notEmpty.signal();
            } catch (Exception e) {
               e.printStackTrace();
            }
            lock.unlock();
        }
    }

我不会得到它,出于什么原因,这不安全?

4

2 回答 2

4

您可以为解锁添加 finally 以确保调用它,而不是可能导致您的 try-catch 的异常路径。

此外,正如您肯定知道的那样,不应将捕获异常并仅将其记录下来以进行生产。

} finally {
            try {
                notEmpty.signal();
            } catch (Exception e) {
               e.printStackTrace();
            }
            finally {
               lock.unlock();
            }
        }
于 2013-10-17T14:15:11.097 回答
4

我认为这表明,因为如果您的代码在行上抛出 Throwable 的另一个子类(例如 Error),notEmpty.signal();那么锁将不会被释放。

您可以争辩说,如果出现错误,您的应用程序将关闭,或者Exception在此代码中捕获是正确的做法。我确实同意这一点,但正如 FindBugs 所说,有一些代码路径最终导致锁没有被释放......并且没有什么能阻止开发人员扩展 Throwable :'(。

于 2013-10-17T14:11:22.493 回答