首页 > 文章列表 > SpringBoot中的Scheduled单线程执行问题怎么解决

SpringBoot中的Scheduled单线程执行问题怎么解决

springboot scheduled
274 2023-05-23

SpringBoot中的Scheduled单线程执行问题怎么解决

问题描述

在一次SpringBoot中使用Scheduled定时任务时,发现某一个任务出现执行占用大量资源,会导致其他任务也执行失败。

类似于以下模拟场景,test1定时任务模拟有五秒钟执行时间,这时会同步影响到test2任务的执行,导致test2任务也变成五秒执行一次。

    @Scheduled(fixedRate = 1000)

    public void test1() throws InterruptedException {

        log.info(Thread.currentThread().getName() + " | task01 ");

        Thread.sleep(5000);

    }



    @Scheduled(fixedRate = 2000)

    public void test2() {

        log.info(Thread.currentThread().getName() + " | task02 ");

    }

原因分析:

经过相关资料查阅,发现Scheduled定时任务默认的线程数只有一个,进行定时任务调度时会同步的去调度,一个执行完成后再执行另一个,这是导致该问题的直接原因。

解决方案:

    @Bean

    public TaskScheduler taskScheduler() {

        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();

        // 设置线程数量

        taskScheduler.setPoolSize(50);

        return taskScheduler;

    }

添加一个配置,设置TaskScheduler线程数为多个,这样再执行时就会异步执行了,各个定时任务间互不影响。

补充:

使用以下Java的util包中带的TimerTask也可以进行定时任务的执行。

以下参数中TimerTask是执行的任务,0表示第一次延迟0秒执行,3000表示每3000毫秒执行一次。

						// true表示定时任务创建为守护线程

                        Timer timer = new Timer(true);

                        //timer.scheduleAtFixedRate();

                        timer.schedule(new TimerTask() {

                            @Override

                            public void run() {

                                logger.info(Thread.currentThread().getName() + "************"+ftpGaFilePrefix);

                            }

                        }, 0, 3000);