/** * {@inheritDoc} * * @since 10.0 */ @Override public void addListener(@Nonnull Runnable listener, @Nonnull Executor executor) { Preconditions.checkNotNull(listener, "Runnable was null."); Preconditions.checkNotNull(executor, "Executor was null."); Listener oldHead = listeners; if (oldHead != Listener.TOMBSTONE) { Listener newNode = new Listener(listener, executor); do { newNode.next = oldHead; if (ATOMIC_HELPER.casListeners(this, oldHead, newNode)) { return; } oldHead = listeners; // re-read } while (oldHead != Listener.TOMBSTONE); } // If we get here then the Listener TOMBSTONE was set, which means the future is done, call // the listener. executeListener(listener, executor); }
/** * Sets the result of this {@code Future} unless this {@code Future} has already been cancelled or * set (including {@linkplain #setFuture set asynchronously}). When a call to this method returns, * the {@code Future} is guaranteed to be {@linkplain #isDone done} <b>only if</b> the call was * accepted (in which case it returns {@code true}). If it returns {@code false}, the {@code * Future} may have previously been set asynchronously, in which case its result may not be known * yet. That result, though not yet known, cannot by overridden by a call to a {@code set*} * method, only by a call to {@link #cancel}. * * @param value the value to be used as the result * @return true if the attempt was accepted, completing the {@code Future} */ protected boolean set(@Nullable V value) { Object valueToSet = value == null ? NULL : value; if (ATOMIC_HELPER.casValue(this, null, valueToSet)) { complete(); return true; } return false; }
do { node.setNext(oldHead); if (ATOMIC_HELPER.casWaiters(this, oldHead, node)) { while (true) { LockSupport.parkNanos(this, remainingNanos);
do { node.setNext(oldHead); if (ATOMIC_HELPER.casWaiters(this, oldHead, node)) {
continue restart; } else if (!ATOMIC_HELPER.casWaiters(this, curr, succ)) { // We are unlinking head continue restart; // We raced with an add or complete
if (ATOMIC_HELPER.casValue(AbstractFuture.this, expected, valueToSet)) { complete(); return true;
Object valueToSet = new Cancellation(mayInterruptIfRunning, cause); do { if (ATOMIC_HELPER.casValue(this, localValue, valueToSet)) {
/** * Sets the failed result of this {@code Future} unless this {@code Future} has already been * cancelled or set (including {@linkplain #setFuture set asynchronously}). When a call to this * method returns, the {@code Future} is guaranteed to be {@linkplain #isDone done} <b>only if</b> * the call was accepted (in which case it returns {@code true}). If it returns {@code false}, the * {@code Future} may have previously been set asynchronously, in which case its result may not be * known yet. That result, though not yet known, cannot by overridden by a call to a {@code set*} * method, only by a call to {@link #cancel}. * * @param throwable the exception to be used as the failed result * @return true if the attempt was accepted, completing the {@code Future} */ protected boolean setException(Throwable throwable) { Object valueToSet = new Failure(Preconditions.checkNotNull(throwable)); if (ATOMIC_HELPER.casValue(this, null, valueToSet)) { complete(); return true; } return false; }
void setNext(Waiter next) { ATOMIC_HELPER.putNext(this, next); }
/** Clears the {@link #waiters} list and returns the most recently added value. */ private Waiter clearWaiters() { Waiter head; do { head = waiters; } while (!ATOMIC_HELPER.casWaiters(this, head, Waiter.TOMBSTONE)); return head; }
/** Clears the {@link #listeners} list and returns the most recently added value. */ private Listener clearListeners() { Listener head; do { head = listeners; } while (!ATOMIC_HELPER.casListeners(this, head, Listener.TOMBSTONE)); return head; }
Waiter() { // avoid volatile write, write is made visible by subsequent CAS on waiters field ATOMIC_HELPER.putThread(this, Thread.currentThread()); }