【发布时间】:2011-05-20 01:16:47
【问题描述】:
Future.get(timeout) 在给定超时后不会可靠地抛出 TimeoutException。这是正常行为还是我可以做些什么来使它更可靠?这个测试在我的机器上失败了。但是,如果我睡 3000 而不是 2000,它就会过去。
public class FutureTimeoutTest {
@Test
public void test() throws
ExecutionException,
InterruptedException {
ExecutorService exec = Executors.newSingleThreadExecutor();
final Callable call = new Callable() {
@Override
public Object call() throws Exception {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return 0;
}
};
final Future future = exec.submit(call);
try {
future.get(1000, TimeUnit.MILLISECONDS);
fail("expected TimeoutException");
} catch (TimeoutException ignore) {
}
}
}
【问题讨论】:
-
有趣。是否因平台而异?这可能是 JVM 或操作系统中的错误。
-
我不确定这本身是否真的算作一个错误。在启动另一个线程甚至开始等待 Future 完成之间将经过多少时间肯定会有一些不确定性。是的,1 秒似乎有点多,但我在文档中没有看到任何实际上对截止日期做出硬性保证的内容。
-
我只在 Windows XP 上试过。我同意可能存在不确定性,但是在这个例子中没有发生太多事情。我的真实案例有多个线程,并且在 JNI 中对网络响应有阻塞。在这种情况下,我可以理解超时的一些变化,但在这里?
-
您使用的是什么 JVM/JDK/IDE/TestFramework?这在 Sun JDK6 + jUnit4 + Netbeans 中运行良好。
-
@Seh 指出这可能是线程争用问题:如果您使用
FutureTask将测试更改为在单个线程中运行会发生什么?
标签: java multithreading timeout java.util.concurrent