guava/src/com/google/common/util/concurrent/ExecutionList.java
public void execute() {
    // Lock while we update our state so the add method above will finish adding any listeners
    // before we start to run them.
    RunnableExecutorPair list;
    synchronized (this) {
      if (executed) {
        return;
      }
      executed = true;
      list = runnables;
      runnables = null; // allow GC to free listeners even if this stays around for a while.
    }
    // If we succeeded then list holds all the runnables we to execute. The pairs in the stack are
    // in the opposite order from how they were added so we need to reverse the list to fulfill our
    // contract.
    // This is somewhat annoying, but turns out to be very fast in practice. Alternatively, we could
    // drop the contract on the method that enforces this queue like behavior since depending on it
    // is likely to be a bug anyway.

    // N.B. All writes to the list and the next pointers must have happened before the above
    // synchronized block, so we can iterate the list without the lock held here.
    RunnableExecutorPair reversedList = null;
    while (list != null) {
      RunnableExecutorPair tmp = list;
      list = list.next;
      tmp.next = reversedList;
      reversedList = tmp;
    }
    while (reversedList != null) {
      executeListener(reversedList.runnable, reversedList.executor);
      reversedList = reversedList.next;
    }
  }
public void execute() {
    // Lock while we update our state so the add method above will finish adding any listeners
    // before we start to run them.
    RunnableExecutorPair list;
    synchronized (this) {
      if (executed) {
        return;
      }
      executed = true;
      list = runnables;
      runnables = null; // allow GC to free listeners even if this stays around for a while.
    }
    // If we succeeded then list holds all the runnables we to execute. The pairs in the stack are
    // in the opposite order from how they were added so we need to reverse the list to fulfill our
    // contract.
    // This is somewhat annoying, but turns out to be very fast in practice. Alternatively, we could
    // drop the contract on the method that enforces this queue like behavior since depending on it
    // is likely to be a bug anyway.

    // N.B. All writes to the list and the next pointers must have happened before the above
    // synchronized block, so we can iterate the list without the lock held here.
    RunnableExecutorPair reversedList = null;
    while (list != null) {
      RunnableExecutorPair tmp = list;
      list = list.next;
      tmp.next = reversedList;
      reversedList = tmp;
    }
    while (reversedList != null) {
      executeListener(reversedList.runnable, reversedList.executor);
      reversedList = reversedList.next;
    }
  }
public void execute ( ) { // Lock while we update our state so the add method above will finish adding any listeners // before we start to run them. RunnableExecutorPair list ; synchronized ( this ) { if ( executed ) { return ; } executed = true ; list = runnables ; runnables = null ; // allow GC to free listeners even if this stays around for a while. } // If we succeeded then list holds all the runnables we to execute. The pairs in the stack are // in the opposite order from how they were added so we need to reverse the list to fulfill our // contract. // This is somewhat annoying, but turns out to be very fast in practice. Alternatively, we could // drop the contract on the method that enforces this queue like behavior since depending on it // is likely to be a bug anyway. // N.B. All writes to the list and the next pointers must have happened before the above // synchronized block, so we can iterate the list without the lock held here. RunnableExecutorPair reversedList = null ; while ( list != null ) { RunnableExecutorPair tmp = list ; list = list . next ; tmp . next = reversedList ; reversedList = tmp ; } while ( reversedList != null ) { executeListener ( reversedList . runnable , reversedList . executor ) ; reversedList = reversedList . next ; } }
Runs this execution list, executing all existing pairs in the order they were added. However,
note that listeners added after this point may be executed before those previously added, and
note that the execution order of all listeners is ultimately chosen by the implementations of
the supplied executors.

<p>This method is idempotent. Calling it several times in parallel is semantically equivalent
to calling it exactly once.

@since 10.0 (present in 1.0 as {@code run})
Runs this execution list executing all existing pairs in the order they were added . However note that listeners added after this point may be executed before those previously added and note that the execution order of all listeners is ultimately chosen by the implementations of the supplied executors .