package de.invesdwin.util.concurrent; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.annotation.concurrent.NotThreadSafe; import de.invesdwin.util.error.Throwables; @NotThreadSafe final class WrappedRunnable implements Runnable { private final String parentThreadName; private final Runnable delegate; private final WrappedExecutorService parent; private WrappedRunnable(final WrappedExecutorService parent, final Runnable delegate, final boolean skipWaitOnFullPendingCount) throws InterruptedException { if (delegate instanceof WrappedRunnable) { throw new IllegalArgumentException("delegate should not be an instance of " + getClass().getSimpleName()); } this.parentThreadName = Thread.currentThread().getName(); this.delegate = delegate; this.parent = parent; if (parent != null) { parent.incrementPendingCount(skipWaitOnFullPendingCount); } } @Override public void run() { Threads.updateParentThreadName(parentThreadName); try { delegate.run(); } catch (final Throwable t) { if (parent != null && parent.isLogExceptions()) { Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), t); } throw Throwables.propagate(t); } finally { if (parent != null) { parent.decrementPendingCount(); } } } static Collection<WrappedRunnable> newInstance(final WrappedExecutorService parent, final Collection<Runnable> delegates) throws InterruptedException { final List<WrappedRunnable> ret = new ArrayList<WrappedRunnable>(delegates.size()); boolean skipWaitOnFullPendingCount = false; for (final Runnable delegate : delegates) { ret.add(new WrappedRunnable(parent, delegate, skipWaitOnFullPendingCount)); skipWaitOnFullPendingCount = true; } return ret; } static WrappedRunnable newInstance(final WrappedExecutorService parent, final Runnable delegate) throws InterruptedException { return new WrappedRunnable(parent, delegate, false); } }