1.在SpringBoot项目中使用ThreadPoolExecutor:
SpringBoot中可以通过创建一个配置类来定义ThreadPoolExecutor,然后在需要使用的地方直接注入即可。
@Configuration
public class ThreadPoolConfig {
@Bean
public Executor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(5);
//配置最大线程数
executor.setMaxPoolSize(50);
//配置队列大小
executor.setQueueCapacity(1000);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("async-service-");
executor.initialize();
return executor;
}
}
在需要使用的地方通过@Autowired注入ThreadPoolExecutor即可。
@Service
public class ExampleService {
@Autowired
private Executor asyncServiceExecutor;
//...
}
2.ThreadPoolExecutor的工作流程:
ThreadPoolExecutor在执行execute方法时,首先判断核心线程数是否已满,如果没有满则创建一个新的核心线程来执行传入的任务。如果核心线程已满,那么就将任务放入到队列中。如果队列已满,那么就尝试创建非核心线程来执行任务。如果非核心线程已满,那么就执行拒绝策略。
3.ThreadPoolExecutor的配置:
主要配置参数有:
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:空闲线程的存活时间
unit:存活时间的单位
workQueue:任务队列
threadFactory:线程工厂,用于创建新的线程
handler:拒绝策略
4.示例:下面给出一个使用ThreadPoolExecutor的示例:
public class ThreadPoolExample {
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 10;
private static final long KEEP_ALIVE_TIME = 1;
private static final TimeUnit TIME_UNIT = TimeUnit.MINUTES;
private static final BlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(100);
private static final ThreadPoolExecutor EXECUTOR =
new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT, WORK_QUEUE);
public static void main(String[] args) {
for (int i = 0; i < 50; i++) {
int finalI = i;
EXECUTOR.execute(() -> System.out.println("Running task " + finalI + " on thread " + Thread.currentThread().getName()));
}
EXECUTOR.shutdown();
}
}
5.分析:
此示例创建了一个线程池,拥有5个核心线程,最多可以创建10个线程,当线程数大于5而小于10时,如果空闲线程超过1分钟,那么此线程将被终止。任务队列的长度为100,也就是说最多可以缓存100个待执行的任务。
6.ThreadPoolExecutor创建线程池的方式:
ThreadPoolExecutor创建线程池主要使用以下两种方式:
使用ThreadPoolExecutor的构造方法
使用Executors工具类的静态工厂方法
7.参数解释:
corePoolSize:线程池的基本大小
maximumPoolSize:线程池最大线程数
workQueue:线程池中的任务队列.常用的有三种队列,SynchronousQueue,LinkedBlockingDeque,ArrayBlockingQueue.
keepAliveTime:线程池的工作线程空闲后,保持存活的时间。所以,如果任务很多,并且每个任务执行的时间比较短,可以调大时间,提高线程的利用率。
TimeUnit:keepAliveTime的时间单位
threadFactory:每次创建新的线程工厂
RejectedExecutionHandler:当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理