How can I wrap a method so that I can kill its execution if it exceeds a specified timeout?

carrier picture carrier · Oct 27, 2008 · Viewed 9.1k times · Source

I have a method that I would like to call. However, I'm looking for a clean, simple way to kill it or force it to return if it is taking too long to execute.

I'm using Java.

to illustrate:

logger.info("sequentially executing all batches...");
for (TestExecutor executor : builder.getExecutors()) {
logger.info("executing batch...");
executor.execute();
}

I figure the TestExecutor class should implement Callable and continue in that direction.

But all i want to be able to do is stop executor.execute() if it's taking too long.

Suggestions...?

EDIT

Many of the suggestions received assume that the method being executed that takes a long time contains some kind of loop and that a variable could periodically be checked. However, this is not the case. So something that won't necessarily be clean and that will just stop the execution whereever it is is acceptable.

Answer

Alex picture Alex · Oct 27, 2008

You should take a look at these classes : FutureTask, Callable, Executors

Here is an example :

public class TimeoutExample {
    public static Object myMethod() {
        // does your thing and taking a long time to execute
        return someResult;
    }

    public static void main(final String[] args) {
        Callable<Object> callable = new Callable<Object>() {
            public Object call() throws Exception {
                return myMethod();
            }
        };
        ExecutorService executorService = Executors.newCachedThreadPool();

        Future<Object> task = executorService.submit(callable);
        try {
            // ok, wait for 30 seconds max
            Object result = task.get(30, TimeUnit.SECONDS);
            System.out.println("Finished with result: " + result);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        } catch (TimeoutException e) {
            System.out.println("timeout...");
        } catch (InterruptedException e) {
            System.out.println("interrupted");
        }
    }
}