基本上,如果我删除不必要的东西,我会有这段代码:
public class Foo {
private volatile boolean isFinished = false;
private long timeOut = 60 * 1000;
...
// Called asynchronously from another thread
public setFinished(boolean value) {
isFinished = value;
}
public wait() {
...
long start = SystemClock.uptimeMillis();
while(!isFinished && (SystemClock.uptimeMillis() - start) <= timeOut) {
...
}
if (isFinished) {
// Log success!!!
...
}
else {
// Log time out!!!
...
}
}
}
此代码在95%的时间内都有效。日志文件类似于:
`wait()` is called waiting starts
`setFinished(true)` is called
`setFinished(true)` returns
"success" entry in the log
但有时,根据日志文件会发生以下情况:
`wait()` is called waiting starts
`setFinished(true)` is called
`setFinished(true)` returns
about 60 seconds pass
"time out" entry in the log
有什么想法吗?
答案 0 :(得分:1)
我唯一的猜测是这三点内部有阻止循环执行的东西:
while(!isFinished && (SystemClock.uptimeMillis() - start) <= timeOut) {
...
}
更新:您可能还会尝试使用System.currentTimeMillis()
,因为uptimeMillis()
时钟因环境变化而停止。
答案 1 :(得分:0)
如果isFinished
只从false转换为true,并且如果while循环已退出,那么isFinished
必须为真。
即使您未指定volatile
(在实践中)也是如此,并且鉴于您指定volatile
(理论上和实践中都是如此),情况肯定是这样。
因此我的猜测是第一个假设是假的。如果我是你,我会试试这个:
// Called asynchronously from another thread
public setFinished(boolean value) {
if(!value){
throw new AssertionError("huh?");
}
isFinished = value;
}
看看会发生什么。