【线程池】实现多线程并发定时任务

一、为什么需要配置多线程定时任务

springboot中通过注解 @Scheduled 注解的方法都是一个定时执行的任务, 默认都是单线程的,就算是多个定时任务也是在同一个单线程(scheduled-1)中运行, 如果其中某一个定时任务产生了阻塞,那么会导致项目中其他所有的定时任务线程都不执行。后果非常严重,故而需要配置多线程定时任务。

二、单线程定时任务

导入依赖

<dependencies>

 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
 </dependency>

 <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
 </dependency>

 <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
 </dependency>

</dependencies>

创建定时任务

@Slf4j
@Component
public class ScheduledService {
    
    

	/**
	 * fixedRate:定义一个按一定频率执行的定时任务
	 * fixedDelay:定义该任务延迟执行时间。
	 * cron:通过表达式来配置任务执行时间
	*/
   @Scheduled(cron = "0/5 * * * * *")
   public void scheduled(){
    
    
       log.info("=====>>>>>使用cron  {}",System.currentTimeMillis());
   }

   @Scheduled(fixedRate = 5000)
   public void scheduled1() {
    
    
       log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
   }

   @Scheduled(fixedDelay = 5000)
   public void scheduled2() {
    
    
       log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
   }
   
}

在主类上使用@EnableScheduling注解开启对定时任务的支持,然后启动项目

@SpringBootApplication
@EnableScheduling
public class WebApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(WebApplication.class,args);
    }
}

可以看到三个定时任务都已经执行,并且使同一个线程中串行执行,如果只有一个定时任务,这样做肯定没问题,当定时任务增多,如果一个任务卡死,会导致其他任务也无法执行。
在这里插入图片描述

三、多线程定时任务

在SpringBoot项目中一般使用config配置类的方式添加配置,所以新建一个AsyncConfig类。

@Configuration
@EnableAsync
public class AsyncConfig {
    
    

    /*
     *此处成员变量应该使用@Value从配置中读取
    */
   private int corePoolSize = 10;
   private int maxPoolSize = 200;
   private int queueCapacity = 10;

   @Bean
   public Executor taskExecutor() {
    
    
       ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
       executor.setCorePoolSize(corePoolSize);
       executor.setMaxPoolSize(maxPoolSize);
       executor.setQueueCapacity(queueCapacity);
       executor.initialize();
       return executor;
   }

}

然后在定时任务的类或者方法上添加@Async

@Slf4j
@Component
public class ScheduledService {
    
    

	/**
	 * fixedRate:定义一个按一定频率执行的定时任务
	 * fixedDelay:定义该任务延迟执行时间。
	 * cron:通过表达式来配置任务执行时间
	*/
   @Async
   @Scheduled(cron = "0/5 * * * * *")
   public void scheduled(){
    
    
       log.info("=====>>>>>使用cron  {}",System.currentTimeMillis());
   }
   
   @Async
   @Scheduled(fixedRate = 5000)
   public void scheduled1() {
    
    
       log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
   }
   
   @Async
   @Scheduled(fixedDelay = 5000)
   public void scheduled2() {
    
    
       log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
   }
   
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_46638350/article/details/130926688