Spring Boot @Scheduled 是同步还是异步,单线程还是多线程?

@schedule刚开始用的时候回遇到一些坑,主要就是他的同步、异步、多线程的配置问题,这篇文章介绍了@schedule的使用方法,读者遇到问题时可以参考下。

1. 问题

@schedule注解默认是同步且单线程的,如果定时任务比较多或者有的定时任务比较耗时,会影响到其他定时任务的执行

@Component
public class TestSchedule {
    public  static  int i = 0;
    @Scheduled(cron = "* * * * * ?")
    public void test() throws InterruptedException {
        System.out.println(i++);
        Thread.sleep(1000 * 100);
    }
}

2. 解决方法

我们可以通过以下三种方法将其配置为多线程模式:

第一种: 增加配置类

两种方式:

@Configuration
public class ScheduleConfig {

       @Bean

    public TaskScheduler taskScheduler() {

        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();

        //核心线程池数量,方法: 返回可用处理器的Java虚拟机的数量。

        taskScheduler.setPoolSize(Runtime.getRuntime().availableProcessors() * 2);

        return taskScheduler;

    }

}

 

@Configuration

public class ScheduleConfig1 implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(
                new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2)
        );
    }
}

第二种:配置文件添加task配置

spring:
  task:
    scheduling:
      pool:
        size: 8  #配置Scheduled定时任务为多线程

通过以上配置,每个任务就变成独立线程,单独执行。但对于单个任务,其仍为同步的,只有该次运行完,才会运行下一次定时任务。如果想把其变为异步任务,可开启异步方法。该方法会导致,同一个任务,即使上一次执行还未完成,只要时间到,就会再次执行该任务

第三种:异步配置

@EnableAsync // 开启异步

@Async
@Scheduled(cron = "* * * * * ?")
public void test() throws InterruptedException {
    System.out.println("TEST1 ==== " + i++);
    Thread.sleep(1000 * 100);
}

 

参考:

https://blog.csdn.net/bblzjp/article/details/128216426

posted @ 2023-03-04 12:35  小log  阅读(2864)  评论(0编辑  收藏  举报