Time limit on individual threads with ExecutorService

后端 未结 5 1070

I have an ExecutorService managing a number of Callables. The tasks that the Callables run are mostly black box transformations and number crunching. Under certain condition

相关标签:
5条回答
  • 2020-12-09 05:38

    Use a ScheduleExecutorService to schedule a task to taskFuture.cancel(true) the long running task when the timeout is reached. If the task finishes before then it won't be cancelled.

    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;
    }
    
    0 讨论(0)
  • 2020-12-09 05:38

    You could get a list of your corresponding Futures (that are created when you submit a Callable) together with its startup time.

    Another task could then check every minute if there are some task running for more than a defined time and if so, invoke cancel(true) in the Future. Done futures would be removed off the list.

    0 讨论(0)
  • 2020-12-09 05:40

    The best way for you to do this would be to introduce one more Executor. You can use a ScheduledExecutorService to cancel all long running tasks for example:

    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);
    }
    
    0 讨论(0)
  • 2020-12-09 05:42

    You can use this method

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

    and set the maximum timeout to one minute. If your thread takes more than that it is just aborted.

    0 讨论(0)
  • 2020-12-09 05:52

    You could cancel the future etc as in the other answers, but you need to make sure that your threads which are "number crunching" can handle the interrupt and terminate gracefully. You say that this a black box operation - how certain are you that the interrupted status of the thread is being checked actively within the black box? If it isn't, you can't cancel it with an interrupt. The black box needs to be written with interruption in mind.

    0 讨论(0)
提交回复
热议问题