如何修复 Sonar 问题 "Remove this call to "wait" 或将其移入 "while" loop"?
How to fix Sonar issue "Remove this call to "wait" or move it into a "while" loop"?
我收到了修复遗留项目中声纳问题的请求,有这样一段代码,每次调用此函数都会暂停 50 毫秒:
synchronized(monitor) {
[...]
try {
[...]
Thread.sleep(config.getWaitTime()); // return 50
} catch (SomeException e) {
log.error(e.getMessage(), e);
}
[...]
}
首先,sonar 要求我将 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());
}
上面的解对吗?如果没有,我该怎么办?
A thread can also wake up without being notified, interrupted, or
timing out, a so-called spurious wakeup. While this will rarely occur
in practice, applications must guard against it by testing for the
condition that should have caused the thread to be awakened, and
continuing to wait if the condition is not satisfied. In other words,
waits should always occur in loops, like this one:
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());
}
围绕 wait()
语句的 while
语句旨在检查 wait()
在 while
中的 logical/function 条件是否被重新调用是 true
但在您的情况下,它永远不会像您将 wait 分配给 false
作为 while 主体的第一个语句。
while
好无奈
这是关联到的 Object.wait(long)
javadoc:
A thread can also wake up without being notified, interrupted, or
timing out, a so-called spurious wakeup. While this will rarely occur
in practice, applications must guard against it by testing for the
condition that should have caused the thread to be awakened, and
continuing to wait if the condition is not satisfied.
我常常完全不相信 Sonar 的建议....
您可以使用计时器来检查所需的时间是否已经过去。但是ugg.
我建议您保留适合您要求的 Thread 方式。
或者如果你想让工具API添加无奈的代码。我当然是在开玩笑:不要那样做!
sonar asked me to change Thread.sleep() to wait()
此处忽略声纳。这是误报。
我收到了修复遗留项目中声纳问题的请求,有这样一段代码,每次调用此函数都会暂停 50 毫秒:
synchronized(monitor) {
[...]
try {
[...]
Thread.sleep(config.getWaitTime()); // return 50
} catch (SomeException e) {
log.error(e.getMessage(), e);
}
[...]
}
首先,sonar 要求我将 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());
}
上面的解对吗?如果没有,我该怎么办?
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:
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());
}
围绕 wait()
语句的 while
语句旨在检查 wait()
在 while
中的 logical/function 条件是否被重新调用是 true
但在您的情况下,它永远不会像您将 wait 分配给 false
作为 while 主体的第一个语句。
while
好无奈
这是关联到的 Object.wait(long)
javadoc:
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied.
我常常完全不相信 Sonar 的建议....
您可以使用计时器来检查所需的时间是否已经过去。但是ugg.
我建议您保留适合您要求的 Thread 方式。
或者如果你想让工具API添加无奈的代码。我当然是在开玩笑:不要那样做!
sonar asked me to change Thread.sleep() to wait()
此处忽略声纳。这是误报。