12

Long story short: I have a collection of Future objects. Some of them are already in progress, some are not. I iterate the collection and call future.cancel(false) which, according to the documentation, should cancel all Futures that are not currently running but should allow all the others to complete.

My question is: How do I know when a particular Future is completed after I have called future.cancel(false)? future.isDone() always returns true because cancel() was indeed called before that and future.get() always throws a CancellationException even though the Future is still running.

Any suggestions?

msrd0
  • 7,816
  • 9
  • 47
  • 82
mdzh
  • 1,030
  • 2
  • 17
  • 34

3 Answers3

1

You could add a flag to your Future implementation which will reflect the actual Future' state

Katerina A.
  • 1,268
  • 10
  • 24
1

Since Future models the future result of a pending computation, and since that result is not forthcoming from a canceled future, it is reasonable that Future gives you no way to find out when the computation whose result has been disposed of will complete. In other words, you'd need another paradigm to achieve your goal with that approach.

If your wish is to wait for all the submitted tasks to complete, the closest thing which is directly supported by the Executor Service API is to shut down the entire executor service and wait for its termination.

If the above does not fit your solution, then I don't see a better approach than some custom solution, for example a custom implementation of Runnable, which does some housekeeping on the side so you can check when it has completed running.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
1

given a Callable<Object> c:

futureTask1 = new FutureTask<Object>(c);
futureTask2 = new FutureTask<Void>(futureTask1, null);

executor.execute(futureTask2);

now if you want the result:

futureTask1.get()

if you're no longer interested in the result:

futureTask1.cancel(mayInterruptIfRunning)

if you want to wait to be sure the code in the callable is not (and will not become) running (whether never called, finished cancelling or finished producing the result):

futureTask2.get()

Even if cancelled before it started working, this waits for the executor to execute the scheduled task (which will to nothing if already cancelled), so this may unnecessariliy wait for other long-running tasks to complete. YMMV

feh
  • 11
  • 2