spring boot默认单线程如何破解?

spring boot默认是单线程的,当有多个定时需要跑的时候,他会等到上一个定时跑完再跑下一个定时,而下一个定时一直处于等待状态,若定时很多的话,严重会引起雪崩。。。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5oiY5oiY55qE5Z2a5p6c,size_20,color_FFFFFF,t_70,g_se,x_16

由上面可以看到我有两个定时,但是用的是一个线程。

方法一:添加@Async注解后发现不再是同一个线程,而是使用多个线程了。

因为这个@Async注解,就相当于new Thread().start(); 所以可以看到现在是两个线程在跑。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5oiY5oiY55qE5Z2a5p6c,size_20,color_FFFFFF,t_70,g_se,x_16

 

方法二:写一个ThreadPoolTaskScheduler注入到容器,则定时任务默认就用的这个定时多线程

 @Bean
 public ThreadPoolTaskScheduler getThreadPoolTaskScheduler(){
    // 设置线程数
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    //最大线程数
    scheduler.setPoolSize(50);
    return scheduler;
 }

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5oiY5oiY55qE5Z2a5p6c,size_20,color_FFFFFF,t_70,g_se,x_16

由此可以看出 也是开了两个线程在跑。

方法三:写一个普通的多线程bean,在每个线程上使用@Async注解

//bean的名称,默认是首字母小写的方法名 
@Bean("threadPoolTaskExecutor")
public ThreadPoolTaskExecutor getThreadPoolTaskExecutor(){
    // 设置线程数
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    //核心线程数
    taskExecutor.setCorePoolSize(25);
    //最大线程数
    taskExecutor.setMaxPoolSize(50);
    //阻塞队列
    taskExecutor.setQueueCapacity(100);
    //初始化线程
    taskExecutor.initialize();
    return taskExecutor;
}

因为@Async异步方法默认使用Spring创建ThreadPoolTaskExecutor。默认核心线程数:8,最大线程数:Integer.MAX_VALUE,队列使用LinkedBlockingQueue,容量是:Integer.MAX_VALUE,空闲线程保留时间:60s,线程池拒绝策略:AbortPolicy。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5oiY5oiY55qE5Z2a5p6c,size_20,color_FFFFFF,t_70,g_se,x_16

 由此也可看出,使用的也是两个线程!

 

自定义线程

//线程池最好是自定义,因为性能等信息可以由开发者自己控制,不然默认使用SimpleAsyncTaskExecutor
@Bean
public Executor getExecutor(){
    // 设置线程数
    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    //最大线程数
    threadPoolTaskExecutor.setMaxPoolSize(20);
    //核心线程池大小
    threadPoolTaskExecutor.setCorePoolSize(10);
    //队列容量
    threadPoolTaskExecutor.setQueueCapacity(200);
    //活跃时间
    threadPoolTaskExecutor.setKeepAliveSeconds(60);
    //线程名称前缀
    threadPoolTaskExecutor.setThreadNamePrefix("taskExecutor-");
    return threadPoolTaskExecutor;
}