/** * {@inheritDoc} */ @Override public void addListener(@Nonnull Runnable listener, @Nonnull Executor executor) { verifyNonnull(listener); verifyNonnull(executor); boolean executeImmediate = false; synchronized (listeners) { if (!notified) { listeners.add(new AbstractMap.SimpleImmutableEntry<Runnable, Executor>(listener, executor)); } else { executeImmediate = true; } } if (executeImmediate) { try { executor.execute(listener); } catch (RuntimeException e) { LOGGER.log(Level.SEVERE, "RuntimeException while executing runnable " + listener + " with executor " + executor, e); } } }
/** * Completes the future with the supplied exception. * * @param throwable the exception. * @return {@code true} if the future is now completed, {@code false} if the future has already been completed. */ public boolean setException(@Nonnull Throwable throwable) { verifyNonnull(throwable); boolean result; synchronized (lock) { if (done) { result = false; } else { done = true; this.throwable = throwable; lock.notifyAll(); result = true; } } if (result) { notifyListeners(); } if (throwable instanceof Error) { throw (Error) throwable; } return result; }