SpringBoot | 线程池创建与使用
欢迎参观我的博客,一个Vue 与 SpringBoot结合的产物:https://poetize.cn
- 博客:https://gitee.com/littledokey/poetize-vue2.git
- 聊天室:https://gitee.com/littledokey/poetize-im-vue3.git
- 后端:https://gitee.com/littledokey/poetize.git
- 七牛云登录/注册地址(文件服务器,CDN):https://s.qiniu.com/Mz6Z32
原文链接:https://poetize.cn/article?id=38
线程池的创建方式
Executors.newSingleThreadExecutor()
:线程只有一个,但是等待队列是Integer.MAX_VALUE
Executors.newCachedThreadPool()
:核心线程数是0,最大线程数有Integer.MAX_VALUE个,SynchronousQueue没有容量,是无缓冲等待队列,是一个不存储元素的阻塞队列
Executors.newFixedThreadPool(5)
:线程数是指定的,等待队列是Integer.MAX_VALUE
Executors.newSingleThreadScheduledExecutor()
:核心线程数为1,但是最大线程数为Integer.MAX_VALUE,等待队列是一个延迟无界队列
Executors.newScheduledThreadPool(5)
:核心线程数是指定的,最大线程数为Integer.MAX_VALUE,等待队列是一个延迟无界队列
自定义线程池
@Configuration
@Slf4j
public class ThreadPoolConfig {
/**
* 获取当前系统的CPU 数目
*/
private static final int CPU_NUMS = Runtime.getRuntime().availableProcessors();
/**
* 线程池核心池的大小
*/
private static final int CORE_POOL_SIZE = CPU_NUMS * 2;
/**
* 线程池的最大线程数
*/
private static final int MAXIMUM_POOL_SIZE = CPU_NUMS * 5;
@Autowired
private PoolProperties poolProperties;
/**
* 线程池配置
*/
@Bean(name = "customExecutor")
public ThreadPoolTaskExecutor customExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
// 核心线程池大小
threadPoolTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
// 最大线程数
threadPoolTaskExecutor.setMaxPoolSize(MAXIMUM_POOL_SIZE);
// 队列容量
threadPoolTaskExecutor.setQueueCapacity(poolProperties.getQueueCapacity());
// 活跃时间
threadPoolTaskExecutor.setKeepAliveSeconds(poolProperties.getKeepAliveSeconds());
// 默认情况下,执行器不会等待任务的终止,它会立即关闭,中断正在进行的任务和清理,剩余的任务队列
threadPoolTaskExecutor.setAwaitTerminationSeconds(poolProperties.getAwaitTerminationSeconds());
// 线程名字前缀
threadPoolTaskExecutor.setThreadNamePrefix(poolProperties.getThreadNamePrefix());
// CallerRunsPolicy:如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化
threadPoolTaskExecutor.initialize();
log.info("TreadPoolConfig 创建核心线程数: {}, 最大线程数: {}", CORE_POOL_SIZE, MAXIMUM_POOL_SIZE);
return threadPoolTaskExecutor;
}
}
任务提交方式
- execute():执行一个任务,没有返回值
- submit():提交一个线程任务,有返回值
submit(Callable<T> task)
:能获取到它的返回值,通过future.get()获取(阻塞直到任务执行完)。一般使用FutureTask + Callable配合使用。
submit(Runnable task, T result)
:能通过传入的载体result间接获得线程的返回值。
submit(Runnable task)
:没有返回值的,就算获取它的返回值也是null
Future.get()
:会使取结果的线程进入阻塞状态,直到线程执行完成之后,唤醒取结果的线程,然后返回结果
SpringBoot异步方法
- 开启:
@EnableAsync
- 使用:
@Async("customExecutor")