0

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).

Salah Eddine Taouririt
  • 24,925
  • 20
  • 60
  • 96
  • 1
    It looks like the problem is in createService method. Methods that can hang forever should throw interrupted exception, else it's hard to kill it (you can always call System.exit which is a bad practice - it kills the whole jvm ). Also see http://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java in case you haven't yet. – Viktor K. Jun 04 '14 at 01:37
  • `createService` is a third-part method, I have no control on it, is there any method to associate the `Task` with some timeout ? – Salah Eddine Taouririt Jun 04 '14 at 01:44
  • Do you have a link to the api documentation? – Viktor K. Jun 04 '14 at 01:46
  • `Future` might help you. See http://stackoverflow.com/questions/2275443/how-to-timeout-a-thread – zella Jun 04 '14 at 02:14
  • It seems that the operation fires an `Exception` After a long timeout. – Salah Eddine Taouririt Jun 04 '14 at 02:18

2 Answers2

5

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!";
    }
}
zella
  • 4,645
  • 6
  • 35
  • 60
  • 6
    Here the `future.cancel(true)` in `TimeoutException` handling part will just set the interrupt flag of future thread to `true` right? It wouldn't guarantee the future actually stops and kills the task in progress. – krackoder Oct 31 '18 at 21:17
-1

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
Ilya
  • 29,135
  • 19
  • 110
  • 158
  • That still won't kill the task itself. It just means the caller gives up on the blocking `get`. If `createService` is interruptible the caller could try `future.cancel(true)` but otherwise they're out of luck. – Thorn G Jun 04 '14 at 02:57
  • 4
    Calling `future.get` on the `javafx` thread will bock the UI. – Salah Eddine Taouririt Jun 04 '14 at 03:59