在程序开发过程中为了充分合理的协调利用系统资源【CPU、Memory、I/O等】,避免频繁地创建与销毁线程资源问题,常用解决方案是创建线程池,如下是个人设计的动态可伸缩线程池方案。
/**
* 动态可伸缩线程池
*
* @author <a href="mailto:tansheng526@163.com">tansheng</a>
* @version $$Id$$
* @since 1.0
*/
@Slf4j
public class ThreadHelper {
public static final int MAXINUM_AVAILABLE_PROCESSOR_SIZE = Runtime.getRuntime().availableProcessors();
public static final int MAXINUM_POOL_SIZE =64;
private static final String THREAD_DEFAULT_NAME = "ipig";
private static int corePoolSize = MAXINUM_AVAILABLE_PROCESSOR_SIZE;
private static int maxinumPoolSize = MAXINUM_AVAILABLE_PROCESSOR_SIZE;
private static int queueCapacity = MAXINUM_AVAILABLE_PROCESSOR_SIZE;
private static int waitMillis = 1000;
private static int keepAliveSeconds = 300;
private static String threadName = THREAD_DEFAULT_NAME;
private static volatile ExecutorService executorService = null;
private static volatile BlockingQueue queue = null;
private static volatile LongAdder threadNumber = new LongAdder();
private static volatile boolean daemon = true;
static {
if (MAXINUM_AVAILABLE_PROCESSOR_SIZE < 4) {
corePoolSize = 4;
}
maxinumPoolSize = corePoolSize * 3;
if (maxinumPoolSize>MAXINUM_POOL_SIZE) {
maxinumPoolSize=MAXINUM_POOL_SIZE;
}
queueCapacity = corePoolSize * 2;
queue = new ArrayBlockingQueue(queueCapacity);
}
/**
* getThreadExecutor
*
* @return
*/
private static ExecutorService getThreadExecutor() {
if (executorService == null) {
synchronized (ThreadHelper.class) {
if (executorService == null) {
ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
threadNumber.increment();
Thread thread = new Thread(runnable, threadName + SymbolCnst.MIDLINE +
threadNumber.longValue() + SymbolCnst.MIDLINE + DateTimeHelper.getDateTime());
thread.setDaemon(daemon);
return thread;
}
};
RejectedExecutionHandler rejectedHandler = new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
int depthQueue = 0;
while ((depthQueue = executor.getQueue().size()) >= queueCapacity) {
try {
log.warn("{} thread pool's blocking queue depth is: {}, active threads ={}, " +
" pool size = {},task count = {}", threadName, depthQueue, executor.getActiveCount(),
executor.getPoolSize(), executor.getTaskCount());
Thread.sleep(waitMillis);
} catch (InterruptedException ex) {
}
}
executor.submit(r);
}
};
executorService = new ThreadPoolExecutor(corePoolSize, maxinumPoolSize, keepAliveSeconds,
TimeUnit.SECONDS, queue, threadFactory, rejectedHandler);
Runtime.getRuntime().addShutdownHook(new Thread("application-shutdown-hook") {
@Override
public void run() {
if (executorService != null && !executorService.isShutdown()) {
executorService.shutdown();
}
}
});
}
}
}
return executorService;
}
/**
* execute
* <ul>注:不能保持执行顺序</ul>
*
* @param task
*/
public static <T> Future<T> execute(Callable<T> task) {
if (task == null) {
return null;
}
return getThreadExecutor().submit(task);
}
/**
* execute
* <ul>注:不能保持执行顺序</ul>
*
* @param task
*/
public static void execute(Runnable task) {
if (task == null) {
return;
}
getThreadExecutor().submit(task);
}
/**
* execute
* <ul>注:
* <li>1、不能保持执行顺序</li>
* <li>2、作用在针对Runnable任务需要有返回结果的调用</li>
* </ul>
*
* @param task
* @param result
*/
public static <T> Future<T> execute(Runnable task, T result) {
if (task == null) {
return null;
}
return getThreadExecutor().submit(task, result);
}
/**
* 批量执行
* <ul>注:不能保持执行顺序</ul>
*
* @param tasks
*/
public static <T> List<Future<T>> batchExecute(Collection<? extends Callable<T>> tasks) throws InterruptedException {
List<Future<T>> futures = null;
if (tasks == null || tasks.isEmpty()) {
futures = new ArrayList<Future<T>>(0);
} else {
futures = getThreadExecutor().invokeAll(tasks);
}
return futures;
}
}