/*
* Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.grizzly.threadpool;
import java.util.Queue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import org.glassfish.grizzly.memory.MemoryManager;
import org.glassfish.grizzly.monitoring.DefaultMonitoringConfig;
import org.glassfish.grizzly.utils.DelayedExecutor;
Grizzly thread-pool configuration, which might be used to create and initialize a thread-pool via GrizzlyExecutorService.createInstance(ThreadPoolConfig)
. One can get a default Grizzly ThreadPoolConfig using copy()
and customize it according to the application specific requirements. A ThreadPoolConfig object might be customized in a "Builder"-like fashion:
ThreadPoolConfig.defaultConfig()
.setPoolName("App1Pool")
.setCorePoolSize(5)
.setMaxPoolSize(10);
Author: Oleksiy Stashok, gustav trede
/**
* Grizzly thread-pool configuration, which might be used to create and initialize a thread-pool via
* {@link GrizzlyExecutorService#createInstance(org.glassfish.grizzly.threadpool.ThreadPoolConfig)}. One can get a
* default Grizzly <tt>ThreadPoolConfig</tt> using {@link org.glassfish.grizzly.threadpool.ThreadPoolConfig#copy()} and
* customize it according to the application specific requirements.
*
* A <tt>ThreadPoolConfig</tt> object might be customized in a "Builder"-like fashion: <code>
* ThreadPoolConfig.defaultConfig()
* .setPoolName("App1Pool")
* .setCorePoolSize(5)
* .setMaxPoolSize(10);
* </code>
*
* @author Oleksiy Stashok
* @author gustav trede
*/
public final class ThreadPoolConfig {
private static final ThreadPoolConfig DEFAULT = new ThreadPoolConfig("Grizzly", AbstractThreadPool.DEFAULT_MIN_THREAD_COUNT,
AbstractThreadPool.DEFAULT_MAX_THREAD_COUNT, null, AbstractThreadPool.DEFAULT_MAX_TASKS_QUEUED,
AbstractThreadPool.DEFAULT_IDLE_THREAD_KEEPALIVE_TIMEOUT, TimeUnit.MILLISECONDS, null, Thread.NORM_PRIORITY, true, null, null, -1, null);
Create new Grizzly thread-pool configuration instance. The returned ThreadPoolConfig instance will be
pre-configured with a default values.
Returns: the Grizzly thread-pool configuration instance.
/**
* Create new Grizzly thread-pool configuration instance. The returned <tt>ThreadPoolConfig</tt> instance will be
* pre-configured with a default values.
*
* @return the Grizzly thread-pool configuration instance.
*/
public static ThreadPoolConfig defaultConfig() {
return DEFAULT.copy();
}
protected String poolName;
protected int corePoolSize;
protected int maxPoolSize;
protected Queue<Runnable> queue;
protected int queueLimit = -1;
protected long keepAliveTimeMillis;
protected ThreadFactory threadFactory;
protected int priority = Thread.MAX_PRIORITY;
protected boolean isDaemon;
protected MemoryManager mm;
protected DelayedExecutor transactionMonitor;
protected long transactionTimeoutMillis;
protected ClassLoader initialClassLoader;
Thread pool probes
/**
* Thread pool probes
*/
protected final DefaultMonitoringConfig<ThreadPoolProbe> threadPoolMonitoringConfig;
private ThreadPoolConfig(String poolName, int corePoolSize, int maxPoolSize, Queue<Runnable> queue, int queueLimit, long keepAliveTime, TimeUnit timeUnit,
ThreadFactory threadFactory, int priority, boolean isDaemon, MemoryManager mm, DelayedExecutor transactionMonitor, long transactionTimeoutMillis,
ClassLoader initialClassLoader) {
this.poolName = poolName;
this.corePoolSize = corePoolSize;
this.maxPoolSize = maxPoolSize;
this.queue = queue;
this.queueLimit = queueLimit;
if (keepAliveTime > 0) {
this.keepAliveTimeMillis = TimeUnit.MILLISECONDS.convert(keepAliveTime, timeUnit);
} else {
keepAliveTimeMillis = keepAliveTime;
}
this.threadFactory = threadFactory;
this.priority = priority;
this.isDaemon = isDaemon;
this.mm = mm;
this.transactionMonitor = transactionMonitor;
this.transactionTimeoutMillis = transactionTimeoutMillis;
this.initialClassLoader = initialClassLoader;
threadPoolMonitoringConfig = new DefaultMonitoringConfig<>(ThreadPoolProbe.class);
}
private ThreadPoolConfig(ThreadPoolConfig cfg) {
this.queue = cfg.queue;
this.threadFactory = cfg.threadFactory;
this.poolName = cfg.poolName;
this.priority = cfg.priority;
this.isDaemon = cfg.isDaemon;
this.maxPoolSize = cfg.maxPoolSize;
this.queueLimit = cfg.queueLimit;
this.corePoolSize = cfg.corePoolSize;
this.keepAliveTimeMillis = cfg.keepAliveTimeMillis;
this.mm = cfg.mm;
this.initialClassLoader = cfg.initialClassLoader;
this.threadPoolMonitoringConfig = new DefaultMonitoringConfig<>(ThreadPoolProbe.class);
final ThreadPoolProbe[] srcProbes = cfg.threadPoolMonitoringConfig.getProbesUnsafe();
if (srcProbes != null) {
threadPoolMonitoringConfig.addProbes(srcProbes);
}
this.transactionMonitor = cfg.transactionMonitor;
this.transactionTimeoutMillis = cfg.transactionTimeoutMillis;
}
public ThreadPoolConfig copy() {
return new ThreadPoolConfig(this);
}
Returns: the queue
/**
* @return the queue
*/
public Queue<Runnable> getQueue() {
return queue;
}
Params: - queue – the queue implemenation to use
Returns: the ThreadPoolConfig
with the new Queue
implementation.
/**
*
* @param queue the queue implemenation to use
* @return the {@link ThreadPoolConfig} with the new {@link Queue} implementation.
*/
public ThreadPoolConfig setQueue(Queue<Runnable> queue) {
this.queue = queue;
return this;
}
Returns ThreadFactory
. If ThreadFactory
is set - then priority
, isDaemon
, poolName
settings will not be considered when creating new threads. Returns: the threadFactory
/**
* Returns {@link ThreadFactory}.
*
* If {@link ThreadFactory} is set - then {@link #priority}, {@link #isDaemon}, {@link #poolName} settings will not be
* considered when creating new threads.
*
* @return the threadFactory
*/
public ThreadFactory getThreadFactory() {
return threadFactory;
}
Params: - threadFactory – custom
ThreadFactory
If ThreadFactory
is set - then priority
, isDaemon
, poolName
settings will not be considered when creating new threads.
Returns: the ThreadPoolConfig
with the new ThreadFactory
/**
*
* @param threadFactory custom {@link ThreadFactory} If {@link ThreadFactory} is set - then {@link #priority},
* {@link #isDaemon}, {@link #poolName} settings will not be considered when creating new threads.
*
* @return the {@link ThreadPoolConfig} with the new {@link ThreadFactory}
*/
public ThreadPoolConfig setThreadFactory(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
return this;
}
Returns: the poolname
/**
* @return the poolname
*/
public String getPoolName() {
return poolName;
}
Params: - poolname – the thread pool name.
Returns: the ThreadPoolConfig
with the new thread pool name.
/**
*
* @param poolname the thread pool name.
* @return the {@link ThreadPoolConfig} with the new thread pool name.
*/
public ThreadPoolConfig setPoolName(String poolname) {
this.poolName = poolname;
return this;
}
public int getPriority() {
return priority;
}
public ThreadPoolConfig setPriority(int priority) {
this.priority = priority;
return this;
}
public boolean isDaemon() {
return isDaemon;
}
public ThreadPoolConfig setDaemon(boolean isDaemon) {
this.isDaemon = isDaemon;
return this;
}
Returns: the maxpoolsize
/**
* @return the maxpoolsize
*/
public int getMaxPoolSize() {
return maxPoolSize;
}
Params: - maxPoolSize – the max thread pool size
Returns: the ThreadPoolConfig
with the new max pool size
/**
*
* @param maxPoolSize the max thread pool size
* @return the {@link ThreadPoolConfig} with the new max pool size
*/
public ThreadPoolConfig setMaxPoolSize(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
return this;
}
Returns: the corepoolsize
/**
* @return the corepoolsize
*/
public int getCorePoolSize() {
return corePoolSize;
}
Params: - corePoolSize – the core thread pool size
Returns: the ThreadPoolConfig
with the new core pool size
/**
*
* @param corePoolSize the core thread pool size
* @return the {@link ThreadPoolConfig} with the new core pool size
*/
public ThreadPoolConfig setCorePoolSize(int corePoolSize) {
this.corePoolSize = corePoolSize;
return this;
}
Returns: the thread-pool queue limit. The queue limit value less than 0 means unlimited queue.
/**
* @return the thread-pool queue limit. The queue limit value less than 0 means unlimited queue.
*/
public int getQueueLimit() {
return queueLimit;
}
Params: - queueLimit – the thread-pool queue limit. The queueLimit value less than 0 means unlimited queue.
Returns: the ThreadPoolConfig
with the new queue limite
/**
* @param queueLimit the thread-pool queue limit. The <tt>queueLimit</tt> value less than 0 means unlimited queue.
* @return the {@link ThreadPoolConfig} with the new queue limite
*/
public ThreadPoolConfig setQueueLimit(int queueLimit) {
this.queueLimit = queueLimit;
return this;
}
The max period of time a thread will wait for a new task to process. If the timeout expires and the thread is not a core one (see setCorePoolSize(int)
, setMaxPoolSize(int)
) - then the thread will be terminated and removed from the thread pool. Params: - time – max keep alive timeout. The value less than 0 means no timeout
- unit – time unit
Returns: the ThreadPoolConfig
with the new keep alive time
/**
* The max period of time a thread will wait for a new task to process. If the timeout expires and the thread is not a
* core one (see {@link #setCorePoolSize(int)}, {@link #setMaxPoolSize(int)}) - then the thread will be terminated and
* removed from the thread pool.
*
* @param time max keep alive timeout. The value less than 0 means no timeout
* @param unit time unit
* @return the {@link ThreadPoolConfig} with the new keep alive time
*/
public ThreadPoolConfig setKeepAliveTime(long time, TimeUnit unit) {
if (time < 0) {
keepAliveTimeMillis = -1;
} else {
keepAliveTimeMillis = TimeUnit.MILLISECONDS.convert(time, unit);
}
return this;
}
Returns the max period of time a thread will wait for a new task to process. If the timeout expires and the thread is not a core one (see setCorePoolSize(int)
, setMaxPoolSize(int)
) - then the thread will be terminated and removed from the thread pool. Returns: the keep-alive timeout, the value less than 0 means no timeout
/**
* Returns the max period of time a thread will wait for a new task to process.
*
* If the timeout expires and the thread is not a core one (see {@link #setCorePoolSize(int)},
* {@link #setMaxPoolSize(int)}) - then the thread will be terminated and removed from the thread pool.
*
* @return the keep-alive timeout, the value less than 0 means no timeout
*/
public long getKeepAliveTime(TimeUnit timeUnit) {
if (keepAliveTimeMillis == -1) {
return -1;
}
return timeUnit.convert(keepAliveTimeMillis, TimeUnit.MILLISECONDS);
}
public MemoryManager getMemoryManager() {
return mm;
}
public ThreadPoolConfig setMemoryManager(MemoryManager mm) {
this.mm = mm;
return this;
}
public DefaultMonitoringConfig<ThreadPoolProbe> getInitialMonitoringConfig() {
return threadPoolMonitoringConfig;
}
public DelayedExecutor getTransactionMonitor() {
return transactionMonitor;
}
public ThreadPoolConfig setTransactionMonitor(final DelayedExecutor transactionMonitor) {
this.transactionMonitor = transactionMonitor;
return this;
}
public long getTransactionTimeout(final TimeUnit timeUnit) {
if (transactionTimeoutMillis > 0) {
return timeUnit.convert(transactionTimeoutMillis, TimeUnit.MILLISECONDS);
}
return 0;
}
public ThreadPoolConfig setTransactionTimeout(final long transactionTimeout, final TimeUnit timeunit) {
if (transactionTimeout > 0) {
this.transactionTimeoutMillis = TimeUnit.MILLISECONDS.convert(transactionTimeout, timeunit);
} else {
transactionTimeoutMillis = 0;
}
return this;
}
public ThreadPoolConfig setTransactionTimeout(final DelayedExecutor transactionMonitor, final long transactionTimeout, final TimeUnit timeunit) {
this.transactionMonitor = transactionMonitor;
return setTransactionTimeout(transactionTimeout, timeunit);
}
Returns: the classloader (if any) to be initially exposed by threads from this pool. Since: 2.3
/**
* @return the classloader (if any) to be initially exposed by threads from this pool.
*
* @since 2.3
*/
public ClassLoader getInitialClassLoader() {
return initialClassLoader;
}
Specifies the context classloader that will be used by threads in this pool. If not specified, the classloader of the
parent thread that initialized the pool will be used.
Params: - initialClassLoader – the classloader to be exposed by threads of this pool.
See Also: Returns: the ThreadPoolConfig
Since: 2.3
/**
* Specifies the context classloader that will be used by threads in this pool. If not specified, the classloader of the
* parent thread that initialized the pool will be used.
*
* @param initialClassLoader the classloader to be exposed by threads of this pool.
*
* @return the {@link ThreadPoolConfig}
*
* @see Thread#getContextClassLoader()
*
* @since 2.3
*/
public ThreadPoolConfig setInitialClassLoader(final ClassLoader initialClassLoader) {
this.initialClassLoader = initialClassLoader;
return this;
}
@Override
public String toString() {
return ThreadPoolConfig.class.getSimpleName() + " :\r\n" + " poolName: " + poolName + "\r\n" + " corePoolSize: " + corePoolSize + "\r\n"
+ " maxPoolSize: " + maxPoolSize + "\r\n" + " queue: " + (queue != null ? queue.getClass() : "undefined") + "\r\n" + " queueLimit: "
+ queueLimit + "\r\n" + " keepAliveTime (millis): " + keepAliveTimeMillis + "\r\n" + " threadFactory: " + threadFactory + "\r\n"
+ " transactionMonitor: " + transactionMonitor + "\r\n" + " transactionTimeoutMillis: " + transactionTimeoutMillis + "\r\n" + " priority: "
+ priority + "\r\n" + " isDaemon: " + isDaemon + "\r\n" + " initialClassLoader: " + initialClassLoader;
}
}