org.glassfish.jersey.spi.ThreadPoolExecutorProvider Maven / Gradle / Ivy
Show all versions of jaxrs-ri Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.jersey.spi;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
/**
* Default implementation of the Jersey {@link org.glassfish.jersey.spi.ExecutorServiceProvider executor service provider SPI}.
*
* This provider creates and provisions a shared {@link java.util.concurrent.ThreadPoolExecutor} instance
* using the customizable values for :
*
* - {@link #getCorePoolSize() number of core pool threads}
* - {@link #getMaximumPoolSize() maximum number of threads in the pool}
* - {@link #getKeepAliveTime() thread keep-alive time (in seconds)}
* - {@link #getWorkQueue() backing thread pool work queue}
* - {@link #getBackingThreadFactory() backing thread factory}
* - {@link #getRejectedExecutionHandler() rejected task handler}
*
* Subclasses may override the respective methods to customize the parameters of the provisioned thread pool executor.
*
*
* @author Marek Potociar (marek.potociar at oracle.com)
* @since 2.18
*/
public class ThreadPoolExecutorProvider extends AbstractThreadPoolProvider
implements ExecutorServiceProvider {
private static final long CACHED_POOL_KEEP_ALIVE_DEFAULT_TIMEOUT = 60L;
/**
* Create a new instance of the thread pool executor provider.
*
* @param name provider name. The name will be used to name the threads created & used by the
* provisioned thread pool executor.
*/
public ThreadPoolExecutorProvider(final String name) {
super(name);
}
@Override
public ExecutorService getExecutorService() {
return super.getExecutor();
}
@Override
protected final ThreadPoolExecutor createExecutor(
final int corePoolSize, final ThreadFactory threadFactory, final RejectedExecutionHandler handler) {
return createExecutor(
corePoolSize,
getMaximumPoolSize(),
getKeepAliveTime(),
getWorkQueue(),
threadFactory,
handler);
}
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial parameters.
*
* @param corePoolSize the number of threads to keep in the thread pool, even if they are idle.
* @param maximumPoolSize the maximum number of threads to allow in the thread pool.
* @param keepAliveTime when the number of threads is greater than the core, this is the maximum time (in seconds)
* that excess idle threads will wait for new tasks before terminating.
* @param workQueue the queue to use for holding tasks before they are executed. This queue will hold only the
* {@code Runnable} tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor creates a new thread.
* @param handler the handler to use when execution is blocked because the thread bounds and queue capacities
* are reached.
* @return new configured thread pool instance.
* @throws IllegalArgumentException if one of the following holds:
* {@code corePoolSize < 0}
* {@code keepAliveTime < 0}
* {@code maximumPoolSize <= 0}
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue} or {@code threadFactory} or {@code handler} is {@code null}.
*/
protected ThreadPoolExecutor createExecutor(
final int corePoolSize,
final int maximumPoolSize,
final long keepAliveTime,
final BlockingQueue workQueue,
final ThreadFactory threadFactory,
final RejectedExecutionHandler handler) {
return new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
workQueue,
threadFactory,
handler);
}
/**
* Get the maximum number of threads to allow in the thread pool.
*
* The value from this method is passed as one of the input parameters in a call to the
* {@link #createExecutor(int, int, long, java.util.concurrent.BlockingQueue, java.util.concurrent.ThreadFactory,
* java.util.concurrent.RejectedExecutionHandler)} method.
*
*
* The method can be overridden to customize the maximum number of threads allowed in the provisioned thread pool executor.
* If not customized, the method defaults to {@link java.lang.Integer#MAX_VALUE}.
*
*
* @return maximum number of threads allowed in the thread pool.
*/
protected int getMaximumPoolSize() {
return Integer.MAX_VALUE;
}
/**
* Get the thread keep-alive time (in seconds).
*
* When the number of threads in the provisioned thread pool is greater than the core, this is the maximum time (in seconds)
* that excess idle threads will wait for new tasks before terminating.
*
*
* The value from this method is passed as one of the input parameters in a call to the
* {@link #createExecutor(int, int, long, java.util.concurrent.BlockingQueue, java.util.concurrent.ThreadFactory,
* java.util.concurrent.RejectedExecutionHandler)} method.
*
*
* The method can be overridden to customize the thread keep-alive time in the provisioned thread pool executor.
* If not customized, the method defaults to:
*
* - {@value #CACHED_POOL_KEEP_ALIVE_DEFAULT_TIMEOUT} in case the {@link #getMaximumPoolSize() maximum pool size}
* is equal to {@link java.lang.Integer#MAX_VALUE}
* - {@code 0L} in case the maximum pool size is lower than
* {@code java.lang.Integer#MAX_VALUE}
*
* The default value computation closely corresponds to the thread pool executor configurations used in
* {@link java.util.concurrent.Executors#newCachedThreadPool()} and
* {@link java.util.concurrent.Executors#newFixedThreadPool(int)} methods.
*
*
* @return thread keep-alive time (in seconds) for the provisioned thread pool executor.
*/
protected long getKeepAliveTime() {
return CACHED_POOL_KEEP_ALIVE_DEFAULT_TIMEOUT;
}
/**
* Get the work queue for the provisioned thread pool executor.
*
* The work queue is used to hold the tasks before they are executed by the provisioned thread pool executor.
* The queue will hold only the {@link Runnable} tasks submitted by the {@link ThreadPoolExecutor#execute} method.
*
*
* The value from this method is passed as one of the input parameters in a call to the
* {@link #createExecutor(int, int, long, java.util.concurrent.BlockingQueue, java.util.concurrent.ThreadFactory,
* java.util.concurrent.RejectedExecutionHandler)} method.
*
*
* The method can be overridden to customize the work queue used by the provisioned thread pool executor.
* If not customized, the method defaults to:
*
* - {@link java.util.concurrent.SynchronousQueue} in case the {@link #getMaximumPoolSize() maximum pool size}
* is equal to {@link java.lang.Integer#MAX_VALUE}
* - {@link java.util.concurrent.LinkedBlockingQueue} in case the maximum pool size is lower than
* {@code java.lang.Integer#MAX_VALUE}
*
* The default value computation closely corresponds to the thread pool executor configurations used in
* {@link java.util.concurrent.Executors#newCachedThreadPool()} and
* {@link java.util.concurrent.Executors#newFixedThreadPool(int)} methods.
*
*
* @return work queue for the provisioned thread pool executor.
*/
protected BlockingQueue getWorkQueue() {
return (getMaximumPoolSize() == Integer.MAX_VALUE)
? new SynchronousQueue() : new LinkedBlockingQueue();
}
@Override
public void dispose(final ExecutorService executorService) {
// NO-OP.
}
/**
* Container pre-destroy handler method.
*
* Invoking the method {@link #close() closes} this provider.
*
*/
@PreDestroy
public void preDestroy() {
close();
}
}