[英]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());
}
上述解决方案正确吗? 如果没有,我该怎么办?
线程也可以唤醒,而不会被通知,中断或超时,即所谓的虚假唤醒。 尽管在实践中这种情况很少发生,但是应用程序必须通过测试应该导致线程唤醒的条件来防范它,并在条件不满足时继续等待。 换句话说,等待应该总是在循环中发生 ,就像这样:
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.