Future.cancel (false) returns true to complete the task

Future.cancel (false) should, in my opinion, only return true if it was actually possible to prevent the task from being executed.

But you can see from the code below that this is contradictory.

Since the canceld task should not print "Not expecting this statement!!!"

public class Test {
    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        final boolean[] canceled = { false };
        ScheduledFuture<?> future = executor.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    if (canceled[0])
                        System.out.println("Not expecting this statement!!!");
                } catch (InterruptedException e) {
                }
            }
        }, 0, TimeUnit.SECONDS);
        Thread.sleep(100);
        canceled[0] = future.cancel(false);

        executor.shutdown();
        executor.awaitTermination(2, TimeUnit.SECONDS);
    }
}

      

Unfortunately, the output of this program "Didn't expect this statement !!!"

Can someone explain this behavior.

+3


source to share


2 answers


Because you are calling canceled[0] = future.cancel(false);

with a parameter false

. From the javadoc Future.cancel

:

If the task is already running, the mayInterruptIfRunning parameter determines whether the thread executing the task should be interrupted when it tries to stop the task.

@param mayInterruptIfRunning {@code true} if the thread executing this task should be interrupted; otherwise the execution tasks are performed



When you call cancel

, your task has already started and you allow it to complete, so the cancel operation is indeed successful and returns true

, if you call canceled[0] = future.cancel(true);

you will not see the output.

+5


source


In your code boolean[] canceled

is shared between two threads and there is no synchronized access to this variable. Thus, the results will be unexpected. Also from the documentation https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean) it will return false if the task cannot be canceled, usually because that it has already completed normally. Try adding a log after canceling a task to see which one runs first (although this may not always help)



0


source







All Articles