Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for cancel() on FutureTask

I want to cancel a FutureTask that I get from a ThreadPoolExecutor but I want to be sure the that Callable on the thread pool has stopped it's work.

If I call FutureTask#cancel(false) and then get() (to block until completion) I get a CancelledException. Is this exception thrown immediately or after the task has stopped executing?

like image 255
Jon Tirsen Avatar asked May 18 '11 06:05

Jon Tirsen


People also ask

What is the use of FutureTask in java?

A FutureTask can be used to wrap a Callable or Runnable object. Because FutureTask implements Runnable , a FutureTask can be submitted to an Executor for execution. In addition to serving as a standalone class, this class provides protected functionality that may be useful when creating customized task classes.

What is cancel in Java?

The cancel method takes a single boolean argument. If the argument is true , cancel sends the background task an interrupt. Whether the argument is true or false , invoking cancel changes the cancellation status of the object to true . This is the value returned by isCancelled .

How do you stop future in Java?

You can cancel a future using Future. cancel() method. It attempts to cancel the execution of the task and returns true if it is cancelled successfully, otherwise, it returns false. The cancel() method accepts a boolean argument - mayInterruptIfRunning .

What is future in executor service?

An example of using Future is working with Thread pools. When one submit a task to ExecutorService which is take a long running time, then it returns a Future object immediately. This Future object can be used for task completion and getting result of computation.


1 Answers

Yes, CancellationException is thrown immediately. You may extend FutureTask to add get() method's version which waits until Callable's thread is finished.

public class ThreadWaitingFutureTask<T> extends FutureTask<T> {

    private final Semaphore semaphore;

    public ThreadWaitingFutureTask(Callable<T> callable) {
        this(callable, new Semaphore(1));
    }

    public T getWithJoin() throws InterruptedException, ExecutionException {
        try {
            return super.get();
        }
        catch (CancellationException e) {
            semaphore.acquire();
            semaphore.release();
            throw e;
        }
    }

    private ThreadWaitingFutureTask(final Callable<T> callable, 
                final Semaphore semaphore) {
        super(new Callable<T>() {
            public T call() throws Exception {
                semaphore.acquire();
                try {
                    return callable.call();
                }
                finally {
                    semaphore.release();
                }
            }
        });
        this.semaphore = semaphore;
    }
}
like image 112
Aleksey Otrubennikov Avatar answered Sep 19 '22 11:09

Aleksey Otrubennikov