0

Problem : I have an use case where I want to cancel a task that has already been submitted to an executor service. future.cancel() is not helpful to me as the task does not go to wait() / sleep() state during the execution. Also, adding isInterrupted() is not scalable because of the following reasons,

  1. Many other services are called during the execution and using isInterrupted() before each call is ugly.
  2. If suppose one of the service calls in one of the submitted tasks takes more than X milliseconds, I would want to abort the task and free up the tread.

Here is a sample code on how I am using future.cancel() right now. Is there a way where I can completely abort the submitted task / kill the thread executing the task in the main() function without disturbing the other submitted tasks.

public class Main {

    ExecutorService executorService = newFixedThreadPool(10);

    public static void main(String[] args) {

        Future<Integer> test = new Main().sample();

        try {
            test.get(0, java.util.concurrent.TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            System.out.println("Throwing InterruptedException");
        } catch (java.util.concurrent.ExecutionException e) {
            System.out.println("Throwing ExecutionException");
        } catch (java.util.concurrent.TimeoutException e) {
            System.out.println("Throwing TimeoutException");
        } finally {
            System.out.println(test.cancel(true));
        }
        System.out.println("main() COMPLETED");
    }

    private Future<Integer> sample() {
        return executorService.submit(() -> {
                System.out.println("sample() STARTED");
                anotherSample();
                System.out.println("sample() COMPLETED");
                return 1;
        });
    }

    private void anotherSample() throws Exception {
            System.out.println("anotherSample() STARTED");
            for (int i = 0; i < 100000; i++) {
                // do nothing
            }
            System.out.println("anotherSample() COMPLETED");
    }
}

Output :

Throwing TimeoutException
sample() STARTED
anotherSample() STARTED
true
main() COMPLETED
anotherSample() COMPLETED
sample() COMPLETED
Sathya
  • 58
  • 6
  • Since Future.cancel() just interrupts the thread and not terminates the execution of the task, I would then need to use isInterrupted() check everywhere which is not scalable in my case as there are lots of dependent service calls involved. Also, I would want to terminate the tasks if the execution is not complete within X ms. – Sathya Mar 24 '20 at 18:36
  • Timing out on a future is not terminating the execution of the task. – Sathya Mar 24 '20 at 18:38
  • anotherSample() method seems a bit ugly, i do not see if there is an exit option/way from the for loop inside this method, it will try to finish the thing until i reaches 10000, even whatever you do outer of this thread/block. so better use a wait/notify like code break the for loop. –  Mar 26 '20 at 16:26

0 Answers0