package org.threadly.concurrent.wrapper.limiter;
import java.util.concurrent.Callable;
import org.threadly.concurrent.ContainerHelper;
import org.threadly.concurrent.SchedulerService;
/**
* This class is designed to limit how much parallel execution happens on a provided
* {@link SchedulerService}. This allows the implementor to have one thread pool for all
* their code, and if they want certain sections to have less levels of parallelism (possibly
* because those those sections would completely consume the global pool), they can wrap the
* executor in this class.
* <p>
* Thus providing you better control on the absolute thread count and how much parallelism can
* occur in different sections of the program.
* <p>
* This is an alternative from having to create multiple thread pools. By using this you also are
* able to accomplish more efficiently thread use than multiple thread pools would.
* <p>
* This extends the {@link SubmitterSchedulerLimiter} to add {@link SchedulerService} features.
* This does not cause any performance hits, but does require a source {@link SchedulerService} to
* rely on. If you have a {@link SchedulerService} available this implementation should be
* preferred over the {@link SubmitterSchedulerLimiter}.
*
* @since 4.6.0 (since 2.0.0 at org.threadly.concurrent.limiter)
*/
public class SchedulerServiceLimiter extends SubmitterSchedulerLimiter
implements SchedulerService {
protected final SchedulerService scheduler;
/**
* Constructs a new limiter that implements the {@link SchedulerService}.
*
* @param scheduler {@link SchedulerService} implementation to submit task executions to.
* @param maxConcurrency maximum quantity of runnables to run in parallel
*/
public SchedulerServiceLimiter(SchedulerService scheduler, int maxConcurrency) {
super(scheduler, maxConcurrency);
this.scheduler = scheduler;
}
@Override
public boolean remove(Runnable task) {
// synchronize on this so that we don't consume tasks while trying to remove
synchronized (this) {
// try to remove from scheduler first
if (scheduler.remove(task)) {
return true;
}
return ContainerHelper.remove(waitingTasks, task);
}
}
@Override
public boolean remove(Callable<?> task) {
// synchronize on this so that we don't consume tasks while trying to remove
synchronized (this) {
// try to remove from scheduler first
if (scheduler.remove(task)) {
return true;
}
return ContainerHelper.remove(waitingTasks, task);
}
}
@Override
public int getActiveTaskCount() {
return scheduler.getActiveTaskCount();
}
@Override
public int getQueuedTaskCount() {
return scheduler.getQueuedTaskCount() + waitingTasks.size();
}
@Override
public boolean isShutdown() {
return scheduler.isShutdown();
}
}