11

I'm trying to implement a sample application to test Callable and ExecutorService interfaces.

In my app I have declared:

ExecutorService exSvc = Executors.newSingleThreadExecutor();

Then:

Future<Integer> test = exSvc.submit(
    new Callable<Integer>() {
        public Integer call() {
            for(int i = 0; i < 1000; i++){
                System.out.println(i);
            }
            return 1;
        }
    });

Now I'm trying to stop the process before it terminate, I'm using exSvc.shutdownNow() but it doesn't work.

To stop gracefully a classical Thread I usually use some kind of condition variable. Which is a common approach to follow with ExecutorService?

davioooh
  • 23,742
  • 39
  • 159
  • 250

2 Answers2

19

Future.cancel(true) and ExecutorService.shutdownNow() use thread interruption. As long as you don't make uninterruptable blocking calls in your task, all you need is to handle interrupted condition correctly, something like this:

for(int i = 0; i < 1000; i++){
    // Uses isInterrupted() to keep interrupted status set
    if (Thread.currentThread().isInterrupted()) {
        // Cannot use InterruptedException since it's checked
        throw new RuntimeException(); 
    }
    System.out.println(i);
}

If you make uninterruptable blocking calls (such as network IO), things become more complex, you need to interrupt them manually somehow, for example, by closing the underlying sockets.

axtavt
  • 239,438
  • 41
  • 511
  • 482
  • Is there a way to stop the process without using thread interruption? – davioooh Jul 11 '12 at 09:39
  • It's not clear what exactly do you want. `shutdownNow()` already uses interruption. – axtavt Jul 11 '12 at 09:40
  • Yes, infact I'm asking how to stop it **without** thread interruption. Using `shutdownNow()` is the only way to stop a thread submitted to an `ExecutorService`? – davioooh Jul 11 '12 at 09:44
  • 1
    @davioooh: You can do it using a condition variable, but it's not much different - thread interruption status is just a built-in condition variable for this case. – axtavt Jul 11 '12 at 09:46
  • @axtavt using the shutdown will bring down the entire executorService.. THis executor service might also be processsing few more threads... – Punith Raj Jan 16 '17 at 07:02
  • 1
    Would a file read from the disk be considered uninterruptable call? I starting a thread for each file that I want to search and when the result is found, I want to kill all the still running threads, but 'ExecutorService.shutdownNow()' is not working. – Pedro Gordo May 09 '17 at 17:02
1

This is how I'd do it with a FixedThreadPool, hope it's of some help.

    ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    List<Future<Void>> results = new ArrayList<>();

    for (int i = 0; i < numberOfJobs; i++) {
        MyCallableJob job = new MyCallableJob (...);
        results.add(pool.submit(job));
    }

    for (Future<Void> result : results) {
        try { result.get(); }
        catch (InterruptedException | ExecutionException ignorable) { }
    }

    pool.shutdown();
ioreskovic
  • 5,531
  • 5
  • 39
  • 70