Spring的@Scheduled

Spring的@Scheduled的默认线程池数量为1,也就是说定时任务是单线程执行的。这意味着最多同时只有一个任务在执行。当一个任务还在执行时,其他任务会等待其完成,然后按照其预定的执行策略依次执行。

测试代码:

启动类上加注解@EnableScheduling开启任务调度功能,具体任务调度代码如下:

@Slf4j
@Component
public class Scheduler {

	// 每两秒执行一次
    @Scheduled(fixedRate = 2000)
    public void mockMethod1() {
        long threadId = Thread.currentThread().getId();
        String threadName = Thread.currentThread().getName();
        log.info("mockMethod1 start with current thread id: {}, name: {}", threadId, threadName);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("mockMethod1 end with current thread id: {}, name: {}", threadId, threadName);
    }

    @Scheduled(fixedRate = 2000)
    public void mockMethod2() {
        long threadId = Thread.currentThread().getId();
        String threadName = Thread.currentThread().getName();
        log.info("mockMethod2 start with current thread id: {}, name: {}", threadId, threadName);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("mockMethod2 end with current thread id: {}, name: {}", threadId, threadName);
    }

}

结果:可以看到mockMethod1执行完才会执行mockMethod2,而且是单线程执行
在这里插入图片描述

源码

Spring的@Scheduled_第1张图片

Spring的@Scheduled有个特点就是,确保任务执行完毕后才会再次调度下一次执行

想要同时执行多个Scheduled,怎么办?

解决

1.当如果有程序有多个任务的话需要修改配置,让其变为多线程执行,这种配置不会破坏Scheduled的特点

# 设置任务调度线程名称前缀
spring.task.scheduling.thread-name-prefix=task-schedule-
# 设置任务调度线程池大小
spring.task.scheduling.pool.size=10
# 设置任务调度线程池关闭时等待所有任务完成
spring.task.scheduling.shutdown.await-termination=true

结果
在这里插入图片描述
2.使用@Async配置线程池,这种配置会破坏Scheduled的特点

启动类上加注解@EnableAsync开启异步功能,然后配置线程池

@Configuration
public class AppConfig {

    @Bean("taskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(6); // 设置核心线程数
        executor.setMaxPoolSize(9); // 设置最大线程数
        executor.setQueueCapacity(25); // 设置任务队列容量
        executor.setThreadNamePrefix("executor-");
        return executor;
    }
}

代码上加上异步

@Async("taskExecutor")
@Scheduled(fixedRate = 2000)
public void mockMethod1() {
    long threadId = Thread.currentThread().getId();
    String threadName = Thread.currentThread().getName();
    log.info("mockMethod1 start with current thread id: {}, name: {}", threadId, threadName);
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    log.info("mockMethod1 end with current thread id: {}, name: {}", threadId, threadName);
}

结果
在这里插入图片描述

你可能感兴趣的:(Spring,spring,Scheduled,任务调度)