package org.springside.modules.utils.concurrent.threadpool;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.Validate;
import org.springside.modules.utils.concurrent.threadpool.QueuableCachedThreadPool.ControllableQueue;
/**
* ThreadPool创建的工具类.
*
* 对比JDK Executors中的newFixedThreadPool(), newCachedThreadPool(),newScheduledThreadPool, 提供更多有用的配置项.
*
* 另包含了移植自Tomcat的QueuableCachedPool.
*
* 使用示例如下:
*
* <pre>
* ExecutorService ExecutorService = new FixedThreadPoolBuilder().setPoolSize(10).build();
* </pre>
*
* 参考文章 《Java ThreadPool的正确打开方式》http://calvin1978.blogcn.com/articles/java-threadpool.html
*/
public class ThreadPoolBuilder {
private static RejectedExecutionHandler defaultRejectHandler = new AbortPolicy();
/**
* @see FixedThreadPoolBuilder
*/
public static FixedThreadPoolBuilder fixedPool() {
return new FixedThreadPoolBuilder();
}
/**
* @see CacheedThreadPoolBuilder
*/
public static CachedThreadPoolBuilder cachedPool() {
return new CachedThreadPoolBuilder();
}
/**
* @see ScheduledThreadPoolBuilder
*/
public static ScheduledThreadPoolBuilder scheduledPool() {
return new ScheduledThreadPoolBuilder();
}
/**
* @see QueuableCachedThreadPoolBuilder
*/
public static QueuableCachedThreadPoolBuilder queuableCachedPool() {
return new QueuableCachedThreadPoolBuilder();
}
/**
* 创建FixedThreadPool.
*
* 1. 任务提交时, 如果线程数还没达到poolSize即创建新线程并绑定任务(即poolSize次提交后线程总数必达到poolSize,不会重用之前的线程)
*
* poolSize默认为1,即singleThreadPool.
*
* 2. 第poolSize次任务提交后, 新增任务放入Queue中, Pool中的所有线程从Queue中take任务执行.
*
* Queue默认为无限长的LinkedBlockingQueue, 也可以设置queueSize换成有界的队列.
*
* 如果使用有界队列, 当队列满了之后,会调用RejectHandler进行处理, 默认为AbortPolicy,抛出RejectedExecutionException异常.
* 其他可选的Policy包括静默放弃当前任务(Discard),放弃Queue里最老的任务(DisacardOldest),或由主线程来直接执行(CallerRuns).
*
* 3. 因为线程全部为core线程,所以不会在空闲回收.
*/
public static class FixedThreadPoolBuilder {
private int poolSize = 1;
private int queueSize = -1;
private ThreadFactory threadFactory = null;
private String threadNamePrefix = null;
private Boolean daemon = null;
private RejectedExecutionHandler rejectHandler;
/**
* Pool大小,默认为1,即singleThreadPool
*/
public FixedThreadPoolBuilder setPoolSize(int poolSize) {
Validate.isTrue(poolSize >= 1);
this.poolSize = poolSize;
return this;
}
/**
* 默认为-1, 使用无限长的LinkedBlockingQueue,为正数时使用ArrayBlockingQueue
*/
public FixedThreadPoolBuilder setQueueSize(int queueSize) {
this.queueSize = queueSize;
return this;
}
/**
* 与threadNamePrefix互斥, 优先使用ThreadFactory
*/
public FixedThreadPoolBuilder setThreadFactory(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
return this;
}
/**
* 与ThreadFactory互斥, 优先使用ThreadFactory
*/
public FixedThreadPoolBuilder setThreadNamePrefix(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
return this;
}
/**
* 与threadFactory互斥, 优先使用ThreadFactory
*
* 默认为NULL,不进行设置,使用JDK的默认值.
*/
public FixedThreadPoolBuilder setDaemon(Boolean daemon) {
this.daemon = daemon;
return this;
}
public FixedThreadPoolBuilder setRejectHanlder(RejectedExecutionHandler rejectHandler) {
this.rejectHandler = rejectHandler;
return this;
}
public ThreadPoolExecutor build() {
BlockingQueue<Runnable> queue = null;
if (queueSize < 1) {
queue = new LinkedBlockingQueue<Runnable>();
} else {
queue = new ArrayBlockingQueue<Runnable>(queueSize);
}
threadFactory = createThreadFactory(threadFactory, threadNamePrefix, daemon);
if (rejectHandler == null) {
rejectHandler = defaultRejectHandler;
}
return new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, queue, threadFactory,
rejectHandler);
}
}
/**
* 创建CachedThreadPool.
*
* 1. 任务提交时, 如果线程数还没达到minSize即创建新线程并绑定任务(即minSize次提交后线程总数必达到minSize, 不会重用之前的线程)
*
* minSize默认为0, 可设置保证有基本的线程处理请求不被回收.
*
* 2. 第minSize次任务提交后, 新增任务提交进SynchronousQueue后,如果没有空闲线程立刻处理,则会创建新的线程, 直到总线程数达到上限.
*
* maxSize默认为Integer.Max, 可进行设置.
*
* 如果设置了maxSize, 当总线程数达到上限, 会调用RejectHandler进行处理, 默认为AbortPolicy, 抛出RejectedExecutionException异常.
* 其他可选的Policy包括静默放弃当前任务(Discard),或由主线程来直接执行(CallerRuns).
*
* 3. minSize以上, maxSize以下的线程, 如果在keepAliveTime中都poll不到任务执行将会被结束掉, keeAliveTimeJDK默认为10秒.
* JDK默认值60秒太高,如高达1000线程时,要低于16QPS时才会开始回收线程, 因此改为默认10秒.
*/
public static class CachedThreadPoolBuilder {
private int minSize = 0;
private int maxSize = Integer.MAX_VALUE;
private int keepAliveSecs = 10;
private ThreadFactory threadFactory = null;
private String threadNamePrefix = null;
private Boolean daemon = null;
private RejectedExecutionHandler rejectHandler;
public CachedThreadPoolBuilder setMinSize(int minSize) {
this.minSize = minSize;
return this;
}
public CachedThreadPoolBuilder setMaxSize(int maxSize) {
this.maxSize = maxSize;
return this;
}
/**
* JDK默认值60秒太高,如高达1000线程时,要低于16QPS时才会开始回收线程, 因此改为默认10秒.
*/
public CachedThreadPoolBuilder setKeepAliveSecs(int keepAliveSecs) {
this.keepAliveSecs = keepAliveSecs;
return this;
}
/**
* 与threadNamePrefix互斥, 优先使用ThreadFactory
*/
public CachedThreadPoolBuilder setThreadFactory(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
return this;
}
/**
* 与threadFactory互斥, 优先使用ThreadFactory
*/
public CachedThreadPoolBuilder setThreadNamePrefix(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
return this;
}
/**
* 与threadFactory互斥, 优先使用ThreadFactory
*
* 默认为NULL,不进行设置,使用JDK的默认值.
*/
public CachedThreadPoolBuilder setDaemon(Boolean daemon) {
this.daemon = daemon;
return this;
}
public CachedThreadPoolBuilder setRejectHanlder(RejectedExecutionHandler rejectHandler) {
this.rejectHandler = rejectHandler;
return this;
}
public ThreadPoolExecutor build() {
threadFactory = createThreadFactory(threadFactory, threadNamePrefix, daemon);
if (rejectHandler == null) {
rejectHandler = defaultRejectHandler;
}
return new ThreadPoolExecutor(minSize, maxSize, keepAliveSecs, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), threadFactory, rejectHandler);
}
}
/*
* 创建ScheduledPool.
*/
public static class ScheduledThreadPoolBuilder {
private int poolSize = 1;
private ThreadFactory threadFactory = null;
private String threadNamePrefix = null;
/**
* 默认为1
*/
public ScheduledThreadPoolBuilder setPoolSize(int poolSize) {
this.poolSize = poolSize;
return this;
}
/**
* 与threadNamePrefix互斥, 优先使用ThreadFactory
*/
public ScheduledThreadPoolBuilder setThreadFactory(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
return this;
}
public ScheduledThreadPoolBuilder setThreadNamePrefix(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
return this;
}
public ScheduledThreadPoolExecutor build() {
threadFactory = createThreadFactory(threadFactory, threadNamePrefix, Boolean.TRUE);
return new ScheduledThreadPoolExecutor(poolSize, threadFactory);
}
}
/**
* 从Tomcat移植过来的可扩展可用Queue缓存任务的ThreadPool
*
* @see QueuableCachedThreadPool
*/
public static class QueuableCachedThreadPoolBuilder {
private int minSize = 0;
private int maxSize = Integer.MAX_VALUE;
private int keepAliveSecs = 10;
private int queueSize = 100;
private ThreadFactory threadFactory = null;
private String threadNamePrefix = null;
private Boolean daemon = null;
private RejectedExecutionHandler rejectHandler;
public QueuableCachedThreadPoolBuilder setMinSize(int minSize) {
this.minSize = minSize;
return this;
}
public QueuableCachedThreadPoolBuilder setMaxSize(int maxSize) {
this.maxSize = maxSize;
return this;
}
/**
* LinkedQueue长度, 默认100
*/
public QueuableCachedThreadPoolBuilder setQueueSize(int queueSize) {
this.queueSize = queueSize;
return this;
}
public QueuableCachedThreadPoolBuilder setKeepAliveSecs(int keepAliveSecs) {
this.keepAliveSecs = keepAliveSecs;
return this;
}
/**
* 与threadNamePrefix互斥, 优先使用ThreadFactory
*/
public QueuableCachedThreadPoolBuilder setThreadFactory(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
return this;
}
/**
* 与threadFactory互斥, 优先使用ThreadFactory
*/
public QueuableCachedThreadPoolBuilder setThreadNamePrefix(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
return this;
}
/**
* 与threadFactory互斥, 优先使用ThreadFactory
*
* 默认为NULL,不进行设置,使用JDK的默认值.
*/
public QueuableCachedThreadPoolBuilder setDaemon(Boolean daemon) {
this.daemon = daemon;
return this;
}
public QueuableCachedThreadPoolBuilder setRejectHanlder(RejectedExecutionHandler rejectHandler) {
this.rejectHandler = rejectHandler;
return this;
}
public QueuableCachedThreadPool build() {
threadFactory = createThreadFactory(threadFactory, threadNamePrefix, daemon);
if (rejectHandler == null) {
rejectHandler = defaultRejectHandler;
}
return new QueuableCachedThreadPool(minSize, maxSize, keepAliveSecs, TimeUnit.SECONDS,
new ControllableQueue(queueSize), threadFactory, rejectHandler);
}
}
/**
* 优先使用threadFactory,否则如果threadNamePrefix不为空则使用自建ThreadFactory,否则使用defaultThreadFactory
*/
private static ThreadFactory createThreadFactory(ThreadFactory threadFactory, String threadNamePrefix,
Boolean daemon) {
if (threadFactory != null) {
return threadFactory;
}
if (threadNamePrefix != null) {
if (daemon != null) {
return ThreadPoolUtil.buildThreadFactory(threadNamePrefix, daemon);
} else {
return ThreadPoolUtil.buildThreadFactory(threadNamePrefix);
}
}
return Executors.defaultThreadFactory();
}
}