Skip to content
Advertisement

future.cancel does not work

I have a nice and compact code, which does not work as I expected.

public class Test {

    public static void main(String[] args) {

        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    for (;;) {

                    }
                } finally {
                    System.out.println("FINALLY");
                }

            }
        };

        ExecutorService executor = Executors.newSingleThreadExecutor();

        Future<?> future = executor.submit(r);
        try {
            future.get(3, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            boolean c = future.cancel(true);
            System.out.println("Timeout " + c);
        } catch (InterruptedException | ExecutionException e) {
            System.out.println("interrupted");
        }
        System.out.println("END");

    }

}

The output is :

Timeout true

END

Question: Why does not terminate the future.cancel(true) method the called Runnable? After the program wrote the “END” to the output, the “r” Runnable is still running.

Advertisement

Answer

The problem is that your Runnable is not interruptible: task interruption is a collaborative process in Java and the cancelled code needs to check regularly if it’s been cancelled, otherwise it won’t respond to the interruption.

You can amend you code as follows and it should work as expected:

Runnable r = new Runnable() {
    @Override public void run() {
        try {
            while (!Thread.currentThread().isInterrupted()) {}
        } finally {
            System.out.println("FINALLY");
        }
    }
};
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement