【问题标题】:Probable false positive from Findbugs?Findbugs 可能出现误报?
【发布时间】:2013-03-21 12:25:16
【问题描述】:

请参考以下代码sn-p(去掉多余部分以突出问题案例):

FindBugs 抱怨“方法没有释放所有路径上的锁定”。这是误报吗?如果没有,如何解决?

  try{
      someLock.lock();
     //do something
    } finally{
      if (someLock.isLocked())
        someLock.unlock();
    }

【问题讨论】:

  • 你为什么要测试?你应该做一些Lock.lock();在尝试之前。
  • @dystroy 即使有测试,为什么会有警告?
  • 我不知道,我没有看到失败的路径,但这种构造似乎没有意义。

标签: java findbugs java.util.concurrent


【解决方案1】:

如果isLocked() 扔东西,那么你不会解锁。

我认为isLocked不太可能抛出异常,但是当你锁定时,你必须解锁,测试没有意义。那么为什么不使用the javadoc 中描述的标准模式:

someLock.lock();
try{
    //do something
} finally{
    someLock.unlock();
}

原来如此

  • 这是误报,因为您的代码无法解锁
  • 从某种意义上说,您应该根据建议修复您的代码,这是一个真正的积极因素

【讨论】:

    【解决方案2】:

    被锁定

    查询这个锁是否被任何线程持有。此方法设计用于监控系统状态,不用于同步控制

    不是“用于同步控制”意味着 isLocked 的实现不能保证不受竞争条件的影响,即使我们获得了锁也可能返回 false。

    someLock.lock();
    try{      
     //do something
    } finally{
      someLock.unlock();
    }
    

    boolean locked=false;
    try{      
     someLock.lock();
     locked=true;
     //do something
    } finally{
      if (locked) someLock.unlock();
    }
    

    【讨论】:

    • 好吧,这并不能真正解释警告。
    • @dystroy 我添加了一些说明。我认为 Findbugs 会显示警告,因为 isLocked 不适用于同步控制。
    • 第二个代码似乎没用:如果您锁定,您将解锁,无需测试。
    • @dystroy 如果lock()try...finally 块内; lock() 可能会抛出(未经检查的)异常,finally 将被执行。
    • @Javier - 这就是为什么最好将lock 的调用放在try 块之外。
    【解决方案3】:

    这看起来像是误报,但我想我能理解你为什么会得到它。

    FindBugs 规则最有可能被编码为检查所有路径是否调用unlock ...而不管是否实际需要调用(从锁状态的角度来看)。它很可能不会尝试跟踪锁的状态,并且很可能不知道isLocked 的含义。虽然对您和我来说很明显,如果isLocked 返回false,则无需调用unlock,但并未实施 FindBugs 规则来进行此推断。

    (事实上,在广泛的用例中可靠地进行推理对于 FindBugs 实现者来说是一个难题。我们处于“自动定理证明器”领域......)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-01
      • 1970-01-01
      • 2020-08-30
      相关资源
      最近更新 更多