Commit 636b2fc6 authored by Tuukka Lehtonen's avatar Tuukka Lehtonen

Limit core thread pool size to min(CORES, 8)

This is done for both blocking and non-blocking executor in ThreadUtils
to avoid default creation of 2*CORES threads to mainly idle in the
background which becomes even more non-sensible when there are 24, 32,
64, etc. cores.

Also support system property specification of the amount of non-blocking
thread pool core size.

The old legacy system property simantics.executor.blockingMaxThreads is
also still supported but only used if the new replacement property
simantics.executor.blocking.corePoolSize is not used.

gitlab #678
parent a64df030
......@@ -52,22 +52,60 @@ public class ThreadUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(ThreadUtils.class);
public static final int CORES = Runtime.getRuntime().availableProcessors();
private static final String PROP_EXECUTOR_NON_BLOCKING_CORE_POOL_SIZE = "simantics.executor.nonBlocking.corePoolSize";
private static final String PROP_EXECUTOR_BLOCKING_CORE_POOL_SIZE = "simantics.executor.blocking.corePoolSize";
/**
* Defines the maximum thread pool size of
* {@link #getBlockingWorkExecutor()}. The system will enforce this value to
* be at least Math.max(CORES, 8). It can be configured through the system
* property <em>simantics.executor.blockingMaxThreads</em>.
* @deprecated use {@link #PROP_EXECUTOR_BLOCKING_CORE_POOL_SIZE} instead.
*/
public static final int MAX_BLOCKING_EXECUTOR_THREADS;
private static final String PROP_EXECUTOR_BLOCKING_MAX_THREADS = "simantics.executor.blockingMaxThreads";
static {
String blockingMaxThreadsProp = System.getProperty("simantics.executor.blockingMaxThreads", "" + CORES);
int blockingMaxThreads = CORES;
/**
* Defines the core thread pool size of {@link #getNonBlockingWorkExecutor()}.
* The system will enforce this value to be <code>[CORES, 8]</code>. It can
* be configured through the system property
* {@value #PROP_EXECUTOR_NON_BLOCKING_CORE_POOL_SIZE}.
*/
public static final int NON_BLOCKING_EXECUTOR_CORE_POOL_SIZE;
/**
* Defines the core thread pool size of {@link #getBlockingWorkExecutor()}. The
* system will enforce this value to be at in <code>[CORES, 8]</code>. It can be
* configured through the system property
* {@value #PROP_EXECUTOR_BLOCKING_CORE_POOL_SIZE}.
*/
public static final int BLOCKING_EXECUTOR_CORE_POOL_SIZE;
private final static int parseInt(String s, int defaultValue) {
try {
blockingMaxThreads = Integer.parseInt(blockingMaxThreadsProp);
return s != null ? Integer.parseInt(s) : defaultValue;
} catch (NumberFormatException e) {
return defaultValue;
}
MAX_BLOCKING_EXECUTOR_THREADS = Math.max(Math.max(blockingMaxThreads, 8), CORES);
}
private final static int parseCoreBasedIntProp(String prop, int min, int max) {
int n = Math.min(Math.max(min, CORES), max);
return parseInt(System.getProperty(prop), n);
}
static {
NON_BLOCKING_EXECUTOR_CORE_POOL_SIZE = parseCoreBasedIntProp(PROP_EXECUTOR_NON_BLOCKING_CORE_POOL_SIZE, CORES, 8);
int blockingExecutorCorePoolSize = parseCoreBasedIntProp(PROP_EXECUTOR_BLOCKING_CORE_POOL_SIZE, CORES, 8);
// Backwards compatibility: support old PROP_EXECUTOR_BLOCKING_MAX_THREADS and
// its legacy logic of max(CORES, 8, user-specified-value) if
// PROP_BLOCKING_EXECUTOR_CORE_POOL_SIZE has not been used but
// PROP_EXECUTOR_BLOCKING_MAX_THREADS is.
int specifiedBlockingCorePoolSize = parseInt(System.getProperty(PROP_EXECUTOR_BLOCKING_CORE_POOL_SIZE), -1);
if (specifiedBlockingCorePoolSize != blockingExecutorCorePoolSize) {
int blockingMaxThreads = parseInt(System.getProperty(PROP_EXECUTOR_BLOCKING_MAX_THREADS), -1);
if (blockingMaxThreads > 0) {
blockingExecutorCorePoolSize = Math.max(Math.max(blockingMaxThreads, 8), CORES);
}
}
BLOCKING_EXECUTOR_CORE_POOL_SIZE = blockingExecutorCorePoolSize;
}
/** Never acquire non-blocking executor from this field, private use */
......@@ -133,7 +171,7 @@ public class ThreadUtils {
}
};
NON_BLOCKING_EXECUTOR =
new ScheduledThreadPoolExecutor( CORES, tf );
new ScheduledThreadPoolExecutor( NON_BLOCKING_EXECUTOR_CORE_POOL_SIZE, tf );
}
return NON_BLOCKING_EXECUTOR;
}
......@@ -159,13 +197,7 @@ public class ThreadUtils {
}
};
BLOCKING_EXECUTOR =
// new ThreadPoolExecutor(
// 0,
// MAX_BLOCKING_EXECUTOR_THREADS,
// 3L, TimeUnit.SECONDS,
// new SynchronousQueue<Runnable>(),
// tf);
new ScheduledThreadPoolExecutor(MAX_BLOCKING_EXECUTOR_THREADS, tf);
new ScheduledThreadPoolExecutor(BLOCKING_EXECUTOR_CORE_POOL_SIZE, tf);
}
return BLOCKING_EXECUTOR;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment