【问题标题】:tryLock unreleased resourcetryLock 未释放的资源
【发布时间】:2016-07-01 09:36:26
【问题描述】:

以下代码已被 Fortify 标记为违规(锁的“未释放资源”)

try {
  if (lock.tryLock(1, TimeUnit.SECONDS)) {
    try {
      //do something
    }
    finally {
       lock.unlock();
   }
}
catch (InterruptedException e) {
  // something
}

你能解释一下为什么吗? InterruptedException try/catch 是否应该有 finally 语句?我认为内部尝试也可以处理这种情况。

【问题讨论】:

  • 只是Lock接口吗?
  • 我认为这是一个 Fortify 错误 - 代码看起来不错。
  • @BoristheSpider 我认为你是对的

标签: java multithreading concurrency locking fortify


【解决方案1】:

我可能有一个不错的解决方案:

long timeout = ...;
Lock someLock = ...;
try {
    if (!someLock.tryLock(timeout, TimeUnit.MILLISECONDS)) {
        // TODO: print some error;
        return;
    }
} catch (InterruptedException e) {
    // TODO: print some error;
    return;
}

try{
    // TODO: Some Logic
} finally {
    someLock.unlock();
}

【讨论】:

    【解决方案2】:

    Fortify 文档将unreleased resource bug 描述为:

    程序可能无法释放系统资源。

    您的示例并非如此。如果 tryLock 返回 false 或抛出异常,则表示没有获取锁,没有进入 try 块,也没有要释放的内容(因此外部 try 块中不需要 finally 块)。如果 tryLock 返回 true,则进入内部 try 块,并在 finally 中释放锁。

    您所拥有的似乎与API documentation 建议您这样做的方式相同:

      Lock lock = ...;
      if (lock.tryLock()) {
          try {
              // manipulate protected state
          } finally {
              lock.unlock();
          }
      } else {
          // perform alternative actions
      }
    

    唯一的区别是您的示例使用了超时的 tryLock 覆盖,在这种情况下它返回 false。所以从发布的内容来看,这似乎没问题。

    【讨论】:

    • 还有另一个关键区别:本地 lock 变量。如果 OP 正在引用一个类成员,则在持有锁时可能会替换引用。
    • @shmosel:这是一个有趣的观点。但是,如果要更换锁,似乎会出现更严重的问题。
    • 我并不是说它是,只是 Fortify 不能确定。
    • @shmosel:静态代码分析肯定有其局限性。
    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 2012-01-08
    • 2012-05-04
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多