线程池的7个参数
1、corePoolSize:核心线程数
2、maximumPoolSize:最大线程数
3、keepAliveTime:线程活跃时间
4、TimeUnit:时间单位
5、BlockingQueue:线程池任务队列
6、ThreadFactory:创建线程工厂
7、RejectedExecutionHandler:拒绝策略
线程池的执行流程
任务提交到线程池,如果有空闲的线程会直接执行任务,若没有则先将任务放到阻塞队列中,当阻塞队列已满的时候会判断是否达到了最大线程数,如果没有会创建非核心线程数来执行任务,如果已到达最大线程数则走拒绝策略。拒绝策略有以下四种:
创建线程池方式
1、通过Executors静态方法创建线程池(不推荐使用)
这里列举有四种:newSingleThreadExecutor、newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool
ExecutorService executorService = Executors.newSingleThreadExecutor();
ExecutorService executorService1 = Executors.newCachedThreadPool();
ExecutorService executorService2 = Executors.newFixedThreadPool(8);
ExecutorService executorService3 = Executors.newScheduledThreadPool(8);
newSingleThreadExecutor:顾名思义只有一个线程的线程池,效率较慢
newCachedThreadPool:大小无界的线程池,当主线程提交任务速度比线程池中线程处理任务速度要快时,会不断创建新线程,极端情况下可能造成CPU资源耗尽
newFixedThreadPool:固定线程数的线程池
2、手动创建线程池(推荐)
手动创建线程池可以自定义线程池的核心线程数、最大线程数、线程活跃时间、阻塞队列的大小、拒绝策略等
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author lyy
* @Title:
* @description: 线程池配置类
* @date 2022/9/2 14:44
*/
@Configuration
@EnableAsync
public class ThreadPoolConfig {
//核心线程数
private int corePoolSize = 8;
//最大线程数
private int maxPoolSize = 20;
//阻塞队列的大小
private int queueSize = 2048;
//线程的活跃时间大小
private int keepAliveSeconds = 60;
//线程名称前缀
private String threadNamePrefix = "myThread";
@Bean("threadPoolExecutor")
public ThreadPoolTaskExecutor threadPoolExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
// 获取CPU核心线程数
int core = Runtime.getRuntime().availableProcessors();
corePoolSize = core;
//设置核心线程数,一般根据cpu核数决定
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
//设置最大线程数
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
//设置阻塞队列大小
threadPoolTaskExecutor.setQueueCapacity(queueSize);
//设置线程活跃时间
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
/**
* 设置拒绝策略
* 四种拒绝策略:
* 1、ThreadPoolExecutor.AbortPolicy() 默认为该拒绝策略,会直接抛出异常
* 2、ThreadPoolExecutor.CallerRunsPolicy() 将任务直接给主线程进行处理
* 3、ThreadPoolExecutor.DiscardOldestPolicy() 抛弃旧任务,后续旧任务不会再次被执行
* 4、ThreadPoolExecutor.DiscardPolicy() 直接抛弃当前任务,且不会再次被执行
*/
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 设置线程名称前缀
threadPoolTaskExecutor.setThreadNamePrefix(threadNamePrefix);
//等待所有线程执行完成后关闭线程池
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
//初始化
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}