package sk.stuba.fiit.perconik.utilities.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.round;
import static java.lang.Runtime.getRuntime;
import static java.util.concurrent.Executors.defaultThreadFactory;
import static com.google.common.base.Preconditions.checkArgument;
public final class PlatformExecutors {
private static final int availableProcessorsUpperBound = 32;
private static final float maximumPoolSizeScalingFactor = 10;
private static final int minimumPoolSize = 2;
private static final float defaultPoolSizeScalingFactor = maximumPoolSizeScalingFactor;
private PlatformExecutors() {}
private static int boundedAvailableProcessors() {
return min(getRuntime().availableProcessors(), availableProcessorsUpperBound);
}
private static int maximumPoolSize(final float poolSizeScalingFactor) {
return max(round(min(poolSizeScalingFactor, maximumPoolSizeScalingFactor) * boundedAvailableProcessors()), minimumPoolSize);
}
public static float defaultPoolSizeScalingFactor() {
return defaultPoolSizeScalingFactor;
}
public static ExecutorService newLimitedThreadPool() {
return newLimitedThreadPool(maximumPoolSizeScalingFactor);
}
public static ExecutorService newLimitedThreadPool(final float poolSizeScalingFactor) {
return newLimitedThreadPool(poolSizeScalingFactor, defaultThreadFactory());
}
public static ExecutorService newLimitedThreadPool(final float poolSizeScalingFactor, final ThreadFactory factory) {
checkArgument(poolSizeScalingFactor >= 0);
return new ThreadPoolExecutor(0, maximumPoolSize(poolSizeScalingFactor), 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), factory);
}
}