ExecutorService对各个线程的时间限制

时间:2011-01-27 17:43:34

标签: java multithreading threadpool

我有一个ExecutorService管理一些Callables。 Callables运行的任务主要是黑盒转换和数字运算。在某些条件下,正在转换的数据将会振荡并且线程将花费一个多小时来完成。为了比较,大多数线程在一分钟内完成。

已经发现,长时间运行的线程中的数据并不相关。我想打断任何运行时间超过一定时间的线程。最好的方法是什么?

5 个答案:

答案 0 :(得分:21)

使用ScheduleExecutorService在达到超时时将任务计划为taskFuture.cancel(true)长时间运行的任务。如果任务在此之前完成,则不会被取消。

ExecutorService service = Executors.newFixedThreadPool(N);
ScheduledExecutorService canceller = Executors.newSingleThreadScheduledExecutor();

public <T> Future<T> executeTask(Callable<T> c, long timeoutMS){
   final Future<T> future = service.submit(c);
   canceller.schedule(new Callable<Void>(){
       public Void call(){
          future.cancel(true);
          return null;
       }
    }, timeoutMS, TimeUnit.MILLI_SECONDS);
   return future;
}

答案 1 :(得分:5)

您可以像在其他答案中一样取消未来等,但您需要确保“数字运算”的线程可以处理中断并正常终止。你说这是一个黑盒子操作 - 你是否确定在黑盒子里主动检查线程的中断状态?如果不是,则无法通过中断取消。黑盒子需要记住中断。

答案 2 :(得分:3)

最好的方法是再引入一个Executor。您可以使用ScheduledExecutorService取消所有长时间运行的任务,例如:

ExecutorService service = Executors.newFixedThreadPool(N);

ScheduledExecutorService canceller = Executors.newScheduledThreadPool(1);

public void executeTask(Callable<?> c){
   final Future<?> future = service.submit(c);
   canceller.schedule(new Runnable(){
       public void run(){
          future.cancel(true);
       }
    }, SECONDS_UNTIL_TIMEOUT, TimeUnit.SECONDS);
}

答案 3 :(得分:0)

您可以获得相应期货的清单(在您提交可赎回时创建的)及其启动时间。

如果某个任务运行超过定义的时间,则另一个任务可以检查每分钟,如果是,则在Future中调用cancel(true)。完成的期货将从名单中删除。

答案 4 :(得分:0)

您可以使用此方法

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                              long timeout,
                              TimeUnit unit)
                          throws InterruptedException

并将最大超时设置为一分钟。如果你的线程占用的数量超过了它,那么它就会被中止。