使用ExecutorService的TimeoutTask [英] TimeoutTask using ExecutorService
问题描述
我已经使用ExecutorService实现了TimeoutTask。在下面的方法中,我要提交TimeoutTask,如果它在给定时间内超时,我将取消该任务并关闭执行程序。
I have implmented a TimeoutTask using ExecutorService. In the below method I am submitting the TimeoutTask and if it is timed out in a given time, I cancel the task and shuts down the executor.
private boolean waitForProcessToBeCompleted(long timeOut) {
boolean result = false;
ExecutorService executor = Executors.newSingleThreadExecutor();
// Create a FutureTask which will be run
FutureTask<Boolean> futureTask = new FutureTask<Boolean>(new TimeoutTask());
executor.submit(futureTask); // Run the FutureTask
try {
result = futureTask.get(timeOut, TimeUnit.MILLISECONDS); // Check if FutureTask completed in the given time
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
futureTask.cancel(true);
result = true; // Return True only when timed out
} finally {
executor.shutdownNow(); // Stop the executor
}
return result;
}
运行情况很好,我没有任何问题。
It is running very well and I don't have any issue.
但是,我想知道这是否是最好的代码设计。我只是想知道是否最好使用ExecutorService.submit()返回的Future来获取Callable的返回值或使TimeoutTask超时。例如,
However, I would like to know whether this is the best code design. I was just wondering if it could have been better to use a Future returned by ExecutorService.submit() to get the return value of the Callable or to time out the TimeoutTask. e.g.
Future<?> futureTask = executor.submit(new TimeoutTask()); // Run the FutureTask
try {
result = futureTask.get(timeOut, TimeUnit.MILLISECONDS); // Check if FutureTask completed in the given time
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
futureTask.cancel(true);
result = true; // Return True only when timed out
} finally {
executor.shutdownNow(); // Stop the executor
}
return result;
我正在使用JDK7。
推荐答案
invokeAll 方法可用于自动取消超过超时的任务。这样一来,您就可以在不关闭线程池的情况下取消任务(如果您愿意的话,可以将同一线程池用于其他用途)。
The invokeAll method on ExecutorService can be used to automatically cancel tasks that exceed the timeout. This lets you cancel tasks without shutting down the threadpool (which let's you re-use the same threadpool for other things if you choose).
private boolean waitForProcessToBeCompleted(long timeOut) {
ExecutorService executor = Executors.newSingleThreadExecutor();
List<FutureTask> tasks = new ArrayList<>();
tasks.add(new SomeFutureTaskThing()));
List<Future<Boolean>> results;
try {
results = executor.invokeAll(tasks, timeOut, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Restore interrupt status.
return null;
} catch (ExecutionException e) {
throw new RuntimeException(e.getCause());
}
Future<Boolean> result = results.get(0);
try {
return result.get();
} catch (CancellationException e) {
System.err.println("Timed out");
return null;
}
}
这篇关于使用ExecutorService的TimeoutTask的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!