繁体   English   中英

如何解决Sonar问题“将此呼叫删除为“ wait”或将其移至“ while”循环”?

[英]How to fix Sonar issue “Remove this call to ”wait“ or move it into a ”while“ loop”?

我收到了修复旧项目中声纳问题的请求,有这样的代码段,对此函数的每次调用都将暂停50ms:

synchronized(monitor) {

  [...]

  try {

    [...]

    Thread.sleep(config.getWaitTime()); // return 50
  } catch (SomeException e) {
    log.error(e.getMessage(), e);
  }

  [...]
}

首先,声纳要求我将Thread.sleep()更改为wait()因此将try块更改为:

try {

  [..]

  monitor.wait(config.getWaitTime());
} catch (SomeException e) {
  log.error(e.getMessage(), e);
}

然后,出现另一个问题: Remove this call to "wait" or move it into a "while" loop ,我对多线程没有太多经验,所以我不确定我的解决方法是否正确:

boolean wait = true;
while (wait) {
  wait = false;
  monitor.wait(config.getWaitTime());
}

上述解决方案正确吗? 如果没有,我该怎么办?

Object#wait()Java文档

线程也可以唤醒,而不会被通知,中断或超时,即所谓的虚假唤醒。 尽管在实践中这种情况很少发生,但是应用程序必须通过测试应该导致线程唤醒的条件来防范它,并在条件不满足时继续等待。 换句话说,等待应该总是在循环中发生 ,就像这样:

  synchronized (obj) { while (<condition does not hold>) obj.wait(timeout); ... // Perform action appropriate to condition } 

您的循环看起来不太好,应该是这样的:

while (wait) {
  monitor.wait(config.getWaitTime());
}

当不再需要等待条件时,必须从其他位置设置wait变量。

在此while似乎无助:

boolean wait = true;
while (wait) {
  wait = false;
  monitor.wait(config.getWaitTime());
}

while wait()语句周围的while语句旨在检查是否在while逻辑/函数条件为true重新调用了wait()但在您的情况下,决不会重新调用wait()因为您将wait作为false作为第一个语句而身体。
while是如此无奈。
这是与以下对象关联的Object.wait(long) javadoc

线程也可以唤醒,而不会被通知,中断或超时,即所谓的虚假唤醒。 尽管在实践中这种情况很少发生,但是应用程序必须通过测试应该导致线程唤醒的条件来防范它,并在条件不满足时继续等待。

通常,我对Sonar的建议并不完全信服。
您可以使用计时器检查所需时间是否已过。 但是。
我建议您保留适合您要求的Thread方式。
或者,如果您想使工具API添加无助的代码。 我当然在开玩笑:别那样!

声纳要求我将Thread.sleep()更改为wait()

只是在这里忽略声纳。 这是误报。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM