1

Is there anyway to timeout a scheduled task (kill thread) in Spring if the task takes to long or even hangs because of remote resource unavailability

In my case, tasks can take too long or even hang because they're based on HtmlUnitDriver (Selenium) sequence of steps, but from time to time it hangs and I would like to be able to set a time limit for the thread to execute. Something like 1 minute at most.

I setup a fixed rate execution of 5 minutes with an initial delay of 1 minute.

Thanks in advance

frandevel
  • 747
  • 7
  • 22

2 Answers2

1

I did the same some time ago following this example: example

The basic idea is to put your code in a class implementing Callable or Runnable, then create a FutureTask wherever you are going to invoque your thread with the Callable or Runnable class as parameter. Define an executor , submit your futureTask to the executor, and now you are able to execute the thread for x time inside a try catch block, if your thread ends with an timeoutException you will know that it took too long.

Here is my code:

CallableServiceExecutor callableServiceExecutor = new CallableServiceExecutor();
        FutureTask<> task = new FutureTask<>(callableServiceExecutor);

        ExecutorService executor =  Executors.newSingleThreadExecutor();
        executor.submit(task);

        Boolean exito = true;

        try {

            result = task.get(getTimeoutValidacion() , TimeUnit.SECONDS);

        } catch (InterruptedException e) {
            exito = false;
        } catch (ExecutionException e) {
            exito = false;
        } catch (TimeoutException e) {
            exito = false;
        }

        task.cancel(true);
        executor.shutdown();
Luciano
  • 598
  • 9
  • 21
  • Thanks a lot Luciano, I'll give it a try and come back to you – frandevel Mar 16 '13 at 08:30
  • An important difference here is that I0m using Spring with the @Async annotations, so I do not have full control about the thread initialization and trigger – frandevel Mar 16 '13 at 14:15
  • But nevertheless this gives me a clue about having a main executor thread, running all child threads manually, maybe sleeping for a specific time, and then killing whoever is still alive. Keeping control is what takes importance in at this ppoint – frandevel Mar 16 '13 at 14:17
  • I'm glad it helped, I had a similar problem and this is how I solve it. – Luciano Mar 20 '13 at 17:04
  • 1
    Hi again Luciano, finally it worked, but only being aware that the Callable task must handle the interrupted exception correctly to return from the task to the main execution flow, or thrown an InterruptedException otherwise. I achieved with a normal SingleThreadExecutorService. Thanks a lot for the help. – frandevel Mar 25 '13 at 12:25
-1

See: How to timeout a thread

The short answer is that there is not easy or reliable way to kill a thread due to the limitations of Java's thread implementation. The ExecutorService#shutdown() is sort of a hack and heavy. Its best to deal with this in the task itself e.g. like at the network request level if your making a REST request to timeout on the socket.

Or better if you do some sort of message passing ala Actor model (see Akka) you can send a message from "supervisor" for the Actor to die. Also avoiding blocking by using something like Netty will help.

Community
  • 1
  • 1
Adam Gent
  • 47,843
  • 23
  • 153
  • 203