为什么 Java Future.get(timeout) 不可靠? [英] Why is Java Future.get(timeout) Not Reliable?
问题描述
Future.get(timeout) 在给定的超时后不会可靠地抛出 TimeoutException.这是正常行为还是我可以做些什么来使其更可靠?这个测试在我的机器上失败了.但是,如果我睡 3000 次而不是 2000 次,它就会过去.
Future.get(timeout) does not reliably throw the TimeoutException after the given timeout. Is this normal behavior or can I do something to make this more reliable? This test fails on my machine. However if I sleep for 3000 instead of 2000, it will pass.
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) {
}
}
}
推荐答案
没有理由期望测试通过.鉴于您提交任务以供执行,然后等待其完成,在您等待 Future#get()
之前可能会经过任何时间,让任务有足够的时间来耗尽睡眠持续时间并完成.
There is no reason to expect the test to pass. Given that you submit the task for execution and then wait on its completion, any amount of time could pass before your wait on Future#get()
begins, allowing the task plenty of time to exhaust the sleep duration and complete.
在您的情况下,我们可以假设 Executor
中运行的线程获得焦点,而您通过 test()
运行的主线程暂停,尽管处于可运行状态.至于观察到的将提交的任务拖延两秒和三秒之间的差异,我希望您会发现甚至三秒都不够的情况,这取决于您计算机上的其他进程正在忙于做什么.
In your case, we can assume that the thread running within the Executor
gets focus while your main thread running through test()
is on hold, despite being in a runnable state. As for the observed difference between stalling the submitted task for two and three seconds, I expect you could find situations where even three seconds is insufficient, depending on what other processes are busy doing on your computer.
这篇关于为什么 Java Future.get(timeout) 不可靠?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!