org.compass.core.util.concurrent.ScalingExecutros Maven / Gradle / Ivy
package org.compass.core.util.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author kimchy
*/
public class ScalingExecutros {
/**
* Creates a thread pool that creates new threads as needed, but will reuse
* previously constructed threads when they are available. Calls to
* execute will reuse previously constructed threads if
* available. If no existing thread is available, a new thread will be
* created and added to the pool. No more than max threads will
* be created. Threads that have not been used for a keepAlive
* timeout are terminated and removed from the cache. Thus, a pool that
* remains idle for long enough will not consume any resources other than
* the min specified.
*
* @param min the number of threads to keep in the pool, even if they are
* idle.
* @param max the maximum number of threads to allow in the pool.
* @param keepAliveTime when the number of threads is greater than the min,
* this is the maximum time that excess idle threads will wait
* for new tasks before terminating (in milliseconds).
* @return the newly created thread pool
*/
public static ExecutorService newScalingThreadPool(int min, int max,
long keepAliveTime) {
ScalingQueue queue = new ScalingQueue();
ThreadPoolExecutor executor = new ScalingThreadPoolExecutor(min, max, keepAliveTime, TimeUnit.MILLISECONDS, queue);
executor.setRejectedExecutionHandler(new ForceQueuePolicy());
queue.setThreadPoolExecutor(executor);
return executor;
}
/**
* Creates a thread pool, same as in
* {@link #newScalingThreadPool(int, int, long)}, using the provided
* ThreadFactory to create new threads when needed.
*
* @param min the number of threads to keep in the pool, even if they are
* idle.
* @param max the maximum number of threads to allow in the pool.
* @param keepAliveTime when the number of threads is greater than the min,
* this is the maximum time that excess idle threads will wait
* for new tasks before terminating (in milliseconds).
* @param threadFactory the factory to use when creating new threads.
* @return the newly created thread pool
*/
public static ExecutorService newScalingThreadPool(int min, int max,
long keepAliveTime, ThreadFactory threadFactory) {
ExecutorService executorService = newScalingThreadPool(min, max, keepAliveTime);
((ThreadPoolExecutor) executorService).setThreadFactory(threadFactory);
return executorService;
}
/**
* Creates a thread pool similar to that constructed by
* {@link #newScalingThreadPool(int, int, long)}, but blocks the call to
* execute if the queue has reached it's capacity, and all
* max threads are busy handling requests.
*
* If the wait time of this queue has elapsed, a
* {@link java.util.concurrent.RejectedExecutionException} will be thrown.
*
* @param min the number of threads to keep in the pool, even if they are
* idle.
* @param max the maximum number of threads to allow in the pool.
* @param keepAliveTime when the number of threads is greater than the min,
* this is the maximum time that excess idle threads will wait
* for new tasks before terminating (in milliseconds).
* @param capacity the fixed capacity of the underlying queue (resembles
* backlog).
* @param waitTime the wait time (in milliseconds) for space to become
* available in the queue.
* @return the newly created thread pool
*/
public static ExecutorService newBlockingThreadPool(int min, int max,
long keepAliveTime, int capacity, long waitTime) {
ScalingQueue queue = new ScalingQueue(capacity);
ThreadPoolExecutor executor = new ScalingThreadPoolExecutor(min, max, keepAliveTime, TimeUnit.MILLISECONDS, queue);
executor.setRejectedExecutionHandler(new TimedBlockingPolicy(waitTime));
queue.setThreadPoolExecutor(executor);
return executor;
}
/**
* Creates a thread pool, same as in
* {@link #newBlockingThreadPool(int, int, long, int, long)}, using the
* provided ThreadFactory to create new threads when needed.
*
* @param min the number of threads to keep in the pool, even if they are
* idle.
* @param max the maximum number of threads to allow in the pool.
* @param keepAliveTime when the number of threads is greater than the min,
* this is the maximum time that excess idle threads will wait
* for new tasks before terminating (in milliseconds).
* @param capacity the fixed capacity of the underlying queue (resembles
* backlog).
* @param waitTime the wait time (in milliseconds) for space to become
* available in the queue.
* @param threadFactory the factory to use when creating new threads.
* @return the newly created thread pool
*/
public static ExecutorService newBlockingThreadPool(int min, int max,
long keepAliveTime, int capacity, long waitTime,
ThreadFactory threadFactory) {
ExecutorService executorService = newBlockingThreadPool(min,
max,
keepAliveTime,
capacity,
waitTime);
((ThreadPoolExecutor) executorService).setThreadFactory(threadFactory);
return executorService;
}
/**
* A priority based thread factory, for all Thread priority constants:
* Thread.MIN_PRIORITY, Thread.NORM_PRIORITY, Thread.MAX_PRIORITY;
*
* This factory is used instead of Executers.DefaultThreadFactory to allow
* manipulation of priority and thread owner name.
*
* @param namePrefix a name prefix for this thread
* @return a thread factory based on given priority.
*/
public static ThreadFactory daemonThreadFactory(String namePrefix) {
final ThreadFactory f = Executors.defaultThreadFactory();
final String o = namePrefix + "-";
return new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = f.newThread(r);
/*
* Thread name: owner-pool-N-thread-M, where N is the sequence
* number of this factory, and M is the sequence number of the
* thread created by this factory.
*/
t.setName(o + t.getName());
/* override default definition t.setDaemon(false); */
t.setDaemon(true);
return t;
}
};
}
/**
* A priority based thread factory, for all Thread priority constants:
* Thread.MIN_PRIORITY, Thread.NORM_PRIORITY, Thread.MAX_PRIORITY;
*
* This factory is used instead of Executers.DefaultThreadFactory to allow
* manipulation of priority and thread owner name.
*
* @param priority The priority to be assigned to each thread;
* can be either Thread.MIN_PRIORITY, Thread.NORM_PRIORITY
* or Thread.MAX_PRIORITY.
* @param namePrefix a name prefix for this thread
* @return a thread factory based on given priority.
*/
public static ThreadFactory priorityThreadFactory(int priority, String namePrefix) {
final ThreadFactory f = ScalingExecutros.daemonThreadFactory(namePrefix);
final int p = priority;
return new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = f.newThread(r);
/* override default thread priority of Thread.NORM_PRIORITY */
if (p != Thread.NORM_PRIORITY)
t.setPriority(p);
return t;
}
};
}
/**
* Cannot instantiate.
*/
private ScalingExecutros() {
}
}