package com.jy.rental.thread;
import com.jy.rental.service.impl.AlipayPayServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Locale;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author nanzhou
* @datetime 2019/3/4 上午10:40
* @description: 自定义线程池
* @since JDK 1.8
*/
public class CustomThreadPoolExecutor {
/**
* Logger
*/
private static final Logger logger = LoggerFactory.getLogger(AlipayPayServiceImpl.class);
/**
* 获取活跃的 cpu数量
*/
private static int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
/**
* 保存待执行任务的阻塞队列
*/
private final static BlockingQueue<Runnable> CUSTOM_WORK_QUEUE;
/**
* 核心池以外的线程存活时间
*/
private final static long KEEP_ALIVE_TIME = 10L;
/**
* 核心池以外的线程存活时间单位
*/
private final static TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
/**
* 自定义线程工厂
*/
private static ThreadFactory CUSTOM_THREAD_FACTORY;
/**
* 饱和策略
*/
private static RejectedExecutionHandler CUSTOM_REJECTED_EXECUTION_HANDLER;
static {
CUSTOM_WORK_QUEUE = new LinkedBlockingQueue<>();
CUSTOM_THREAD_FACTORY = new NamedThreadFactory();
CUSTOM_REJECTED_EXECUTION_HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
}
public static void execute(Runnable runnable) {
if (runnable == null) {
return;
}
/**
* 1.当线程池小于 corePoolSize 时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
* 2.当线程池达到 corePoolSize 时,新提交任务将被放入 workQueue 中,等待线程池中任务调度执行
* 3.当 workQueue 已满,且 maximumPoolSize > corePoolSize时,新提交任务会创建新线程执行任务
* 4.当提交任务数超过 maximumPoolSize 时,新提交任务由 RejectedExecutionHandler 处理
* 5.当线程池中超过 corePoolSize 线程,空闲时间达到 keepAliveTime 时,关闭空闲线程
* 6.当设置 allowCoreThreadTimeOut(true) 时,线程池中 corePoolSize 线程空闲时间达到 keepAliveTime 也将关闭
* maximumPoolSize 推荐取值
* 如果是 CPU 密集型任务,就需要尽量压榨CPU,参考值可以设为 NUMBER_OF_CORES + 1 或 NUMBER_OF_CORES + 2
* 如果是 IO 密集型任务,参考值可以设置为 NUMBER_OF_CORES * 2
**/
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,
NUMBER_OF_CORES * 2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT,
CUSTOM_WORK_QUEUE, CUSTOM_THREAD_FACTORY, CUSTOM_REJECTED_EXECUTION_HANDLER);
executorService.execute(runnable);
}
public static Future submit(Callable callable) {
if (callable == null) {
throw new NullPointerException();
}
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,
NUMBER_OF_CORES * 2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT,
CUSTOM_WORK_QUEUE, CUSTOM_THREAD_FACTORY, CUSTOM_REJECTED_EXECUTION_HANDLER);
Future future = executorService.submit(callable);
return future;
}
private static class NamedThreadFactory implements ThreadFactory {
private final AtomicInteger threadNumberAtomicInteger = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, String.format(Locale.CHINA, "%s%d", "CustomThreadFactory", threadNumberAtomicInteger.getAndIncrement()));
logger.info("CurrentThread : " + "ThreadName" + thread.getName());
return thread;
}
}
}