使用ExecutorService的TimeoutTask [英] TimeoutTask using ExecutorService

查看:162
本文介绍了使用ExecutorService的TimeoutTask的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆