Adding a thread timeout to methods in Java

Steve Neal Development, Java Programming 1 Comment

When calling a method that could potentially take longer that you’d like to complete, it is possible to write code that will back out after a given time period.

This can happen in numerous circumstances where you’d like an application to maintain a degree of liveness. I’ve used it recently in an application that needed to run a number of external scripts; if the script does not complete, for whatever reason, the timeout ensures the the calling thread does not get blocked and the remaining scripts can be launched.

Here’s the basic idea:

public class TimeoutDemo {

    //maintains a thread for executing the doWork method
    private ExecutorService executor = Executors.newFixedThreadPool(1);

    public void doWork() {
        //perform some long running task here...
    }

    public void doWorkWithTimeout(int timeoutSecs) {

        //set the executor thread working
        final Future<?> future = executor.submit(new Runnable() {
            public void run() {
                try {
                    doWork();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });

        //check the outcome of the executor thread and limit the time allowed for it to complete
        try {
            future.get(timeoutSecs, TimeUnit.SECONDS);
        } catch (Exception e) {
            //ExecutionException: deliverer threw exception
            //TimeoutException: didn't complete within downloadTimeoutSecs
            //InterruptedException: the executor thread was interrupted

            //interrupts the worker thread if necessary
            future.cancel(true);

            log.warn("encountered problem while doing some work", e);
        }
    }
}

The doWork method is the one that will actually do some potentially long running work. The doWorkWithTimeout illustrates how the java.util.concurrent classes can be used to prevent the method from taking too long to complete. When calling the latter method, just specify the timeout period in minutes.

The trick here is that the actual work will be done by a dedicated worker thread. The calling thread will handle the timeout management and also handle any exceptions thrown by the worker.

Variations of this pattern can be used for methods that accept parameters (just make them final) and for ones that return values too (just return the value from the future.get(…) call).

Comments 1

Leave a Reply

Your email address will not be published. Required fields are marked *