How can I cancel a Task after a timeout?


Question

I have some Task execute a I/O blocking operation that can hang (fetching a file from an URL)

task = new Task<List<WSDLOperation>>() {
            @Override
            protected List<WSDLOperation> call() {
                List<WSDLOperation> services = new ArrayList<>();
                try {
                    services = WSDLService.createService(wsdlURL).getOperations();
                } catch (Exception ex) {
                    LOG.log(Level.WARNING, "Can't reach {0}", wsdlURL);
                }
                return services;
            }
        };

    }

The method createService can wait forever without throwing any Exception. (I execute the task using a global (static public)ExecutorService defined in Main class).

1
0
6/4/2014 1:33:01 AM

Accepted Answer

How use future and cancel task after timeout:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Test {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Task t = new Task();
        Future<String> future = executor.submit(t);

        try {
            System.out.println("Started..");
            System.out.println(future.get(5, TimeUnit.SECONDS)); // throws
                                                                    // TimeoutException
            System.out.println("Finished!");
        } catch (TimeoutException e) {
            future.cancel(true);
            System.out.println("Terminated!");
        }
    }
}

class Task implements Callable<String> {
    @Override
    public String call() throws Exception {
        for (int i = 0; i < 1000; i++) {
            Thread.sleep(1000);
            System.out.println("task running!");
        }
        return "Ready!";
    }
}
2
6/4/2014 2:32:27 AM

You are using ExecutorService, so you can do it after submitting the task:

ExecutorService executor = // ...  
Future<?> future = executor.submit(task);
future.get(5, TimeUnit.MINUTES); // timeout 5 mins

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon