{@inheritDoc} If a cancellation attempt succeeds on a Future that had previously been plain #setFuture set asynchronously, then the cancellation will also be propagated to the delegate Future that was supplied in the setFuture call.
(boolean mayInterruptIfRunning)
| 531 | */ |
| 532 | |
| 533 | @CanIgnoreReturnValue |
| 534 | @Override |
| 535 | public boolean cancel(boolean mayInterruptIfRunning) { |
| 536 | Object localValue = value; |
| 537 | if (localValue == null | localValue instanceof AbstractFuture.SetFuture) { |
| 538 | // Try to delay allocating the exception. At this point we may still lose the CAS, but it is |
| 539 | // certainly less likely. |
| 540 | Throwable cause = |
| 541 | GENERATE_CANCELLATION_CAUSES |
| 542 | ? new CancellationException("Future.cancel() was called.") |
| 543 | : null; |
| 544 | Object valueToSet = new Cancellation(mayInterruptIfRunning, cause); |
| 545 | do { |
| 546 | if (ATOMIC_HELPER.casValue(this, localValue, valueToSet)) { |
| 547 | // We call interuptTask before calling complete(), which is consistent with |
| 548 | // FutureTask |
| 549 | if (mayInterruptIfRunning) { |
| 550 | interruptTask(); |
| 551 | } |
| 552 | complete(); |
| 553 | if (localValue instanceof AbstractFuture.SetFuture) { |
| 554 | // propagate cancellation to the future set in setfuture, this is racy, and we don't |
| 555 | // care if we are successful or not. |
| 556 | ((AbstractFuture<?>.SetFuture) localValue).future.cancel(mayInterruptIfRunning); |
| 557 | } |
| 558 | return true; |
| 559 | } |
| 560 | // obj changed, reread |
| 561 | localValue = value; |
| 562 | // obj cannot be null at this point, because value can only change from null to non-null. So |
| 563 | // if value changed (and it did since we lost the CAS), then it cannot be null. |
| 564 | } while (localValue instanceof AbstractFuture.SetFuture); |
| 565 | } |
| 566 | return false; |
| 567 | } |
| 568 | |
| 569 | /** |
| 570 | * Subclasses can override this method to implement interruption of the future's computation. The |
no test coverage detected