Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test if java Future is complete?

I'm tracking execution of a task with standard Future object. There are the following valid states of that task (as I see in Guava code of AbstractFuture class):

  • Running;
  • Completing;
  • Completed successfully or with exception;
  • Cancelled;
  • Interrupted.

Future.isDone() returns true if and only if the state is completed, cancelled or interrupted. Future.isCancelled() returns true if and only if the state is either interrupted or cancelled.

Ok, but I need to check if the task is completed. There is an obvious way to do this:

boolean isCompleted = future.isDone() && !future.isCancelled();

Unfortunatelly, a nasty concurrency bug hides there.

  1. Thread #1 invokes future.isCancelled(). The result is false, because the task is still in progress.
  2. Thread #2 cancels the task calling future.cancel().
  3. Thread #1 invokes future.isDone(). The result is true now.
  4. Evaluation of expression above yields true, and it's incorrect answer.

How to avoid this issue?

like image 680
const.grigoryev Avatar asked Jun 23 '14 15:06

const.grigoryev


1 Answers

You can try calling get(..) with an extremely short timeout. If it returns a value, it was completed. If you get a TimeoutException, it wasn't. If you get any other of the possible exceptions, it was either cancelled, failed, or was interrupted.

like image 155
Sotirios Delimanolis Avatar answered Oct 25 '22 14:10

Sotirios Delimanolis