简体   繁体   English

spring-boot @scheduled 没有在不同的线程中运行?

[英]spring-boot @scheduled not running in different threads?

I am configuring a scheduled task to run in different threads.我正在配置一个计划任务以在不同的线程中运行。 Here is the configuration code这是配置代码

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-sched-pool-");
        threadPoolTaskScheduler.initialize();
        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

Here is the code that uses it这是使用它的代码

@Scheduled(fixedRateString = "2000" )
    public void testaMethod() {

         log.debug("here is the message");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

I am sleeping the thread for 10s with fixedRate of 2s.我正在以 2 秒的固定速率使线程休眠 10 秒。 so I expect to see different threads in the log but I see only one所以我希望在日志中看到不同的线程,但我只看到一个

logs are here日志在这里

{"thread":"my-sched-pool-1","level":"DEBUG","description":"here is the message"}
{"thread":"my-sched-pool-1","level":"DEBUG","description":"here is the message"}
{"thread":"my-sched-pool-1","level":"DEBUG","description":"here is the message"}
{"thread":"my-sched-pool-1","level":"DEBUG","description":"here is the message"}

@Scheduled(fixedRateString = "2000" ) does not gurantee testaMethod be executed every 2 seconds, if the time cost is more than 2s, such as Thread.sleep(10000) , the new task will be put in a queue. @Scheduled(fixedRateString = "2000" )不保证testaMethod每2秒执行一次,如果时间成本超过2s,如Thread.sleep(10000) ,则新任务将被放入队列中。 Only when the old one has been executed, the scheduler will fetch the new task from queue and execute it. 只有在旧的执行时,调度程序才会从队列中获取新任务并执行它。 Since the new task is now the only task in the scheduler, it could be run without creating a new Thread . 由于新任务现在是调度程序中的唯一任务,因此可以在不创建新Thread情况下运行它。

To solve this problem, you can combile @Async and @Scheduled 要解决此问题,您可以组合@Async和@Scheduled

SchedulerConfig SchedulerConfig

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setTaskScheduler(poolScheduler());
    }

    @Bean
    public TaskScheduler poolScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setThreadNamePrefix("poolScheduler");
        scheduler.setPoolSize(POOL_SIZE);
        return scheduler;
    }

}

SchedulerTask 的SchedulerTask

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class SchedulerTask {

    @Autowired
    private AsyncTask asyncTask;

    @Scheduled(fixedRateString = "2000" )
    public void testaMethod() {
        asyncTask.asyncMethod();
    }
}

AsyncTask 的AsyncTask

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

@Component
@EnableAsync
public class AsyncTask {

    private Log log = LogFactory.getLog(AsyncTask.class);

    @Async
    public void asyncMethod() {
        log.debug("here is the message");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Test results 检测结果

11:20:54.682 [poolScheduler1] DEBUG com.test.AsyncTask - here is the message
11:20:56.668 [poolScheduler3] DEBUG com.test.AsyncTask - here is the message
11:20:58.668 [poolScheduler2] DEBUG com.test.AsyncTask - here is the message
11:21:00.669 [poolScheduler6] DEBUG com.test.AsyncTask - here is the message
11:21:02.669 [poolScheduler7] DEBUG com.test.AsyncTask - here is the message
11:21:04.669 [poolScheduler4] DEBUG com.test.AsyncTask - here is the message

spring.task.scheduling.pool.size=20

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM