java - 如何解决声纳问题“删除此调用以“等待”或将其移动到“while”循环中?
问题描述
我收到了修复遗留项目中的声纳问题的请求,有这样的代码段,每次调用此函数都会暂停 50 毫秒:
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
当不再需要等待条件时,必须从别处设置该变量。
推荐阅读
- javascript - 如何删除 JavaScript RowDataPacket 数组中的重复数据
- mysql - SQL:一对多关系——只返回所需的值
- perforce - 将带有 Perforce 工作区的驱动器从一台计算机移动到另一台计算机
- python - 大熊猫的数据框枢轴
- powershell - 创建数组并将其从一个函数传递到另一个函数
- html - bootstrap flex 不将内容居中
- angular - 如何在 Angular 8 中正确实现 HTTP 拦截器?
- flutter - 为什么在 StatefulWidget 中没有定义 build 方法?
- python - uWSGI 应用程序找不到挂载点,但加载了 html
- c# - 如何将返回代码添加到位于单独的 xaml 文件(没有 .cs 文件相关)中的数据模板控件的事件?