package org.warp.commonutils.concurrency.executor; import java.util.concurrent.Callable; import java.util.concurrent.Semaphore; import javax.annotation.Nonnull; public final class PermitReleasingCallableDecorator extends CallableDecorator { @Nonnull private final Runnable queueSizeUpdater; @Nonnull private final Semaphore semaphore; PermitReleasingCallableDecorator(@Nonnull final Callable task, @Nonnull final Runnable queueSizeUpdater, @Nonnull final Semaphore semaphoreToRelease) { super(task); this.queueSizeUpdater = queueSizeUpdater; this.semaphore = semaphoreToRelease; } @Override public T call() throws Exception { try { queueSizeUpdater.run(); } finally { // however execution goes, release permit for next task this.semaphore.release(); return super.call(); } } @Override public final String toString() { return String.format("%s[delegate='%s']", getClass().getSimpleName(), super.toString()); } }