欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring 定时任务 多任务并行执行,多任务多线程 单任务单线程执行实现细节

程序员文章站 2022-05-01 12:43:34
...

前提:spring 定时任务,默认是多任务单线程执行,也就是串行执行的

当前需求:

        1. 多任务多线程执行(不同的定时任务并行执行)

        2.同一个定时任务单线程执行(保证一个定时任务A在执行完成前,A的下一次执行不会开始)

需求实现:

       方案一 ,针对@Scheduled的定时任务,增加配置文件,可实现不同@Scheduled定时任务多线程运行,代码如下

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

/**
 * spring定时任务 多任务多线程配置
 */
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        //开启5个线程,执行现有的定时任务
        taskScheduler.setPoolSize(5);
        //设置线程池中,线程的命名前缀,方便识别那些线程是定时任务的
        taskScheduler.setThreadNamePrefix("cms-job-");
        taskScheduler.initialize();
        scheduledTaskRegistrar.setTaskScheduler(taskScheduler);
    }
}

        方案二 ,原生JDK 实现多任务多线程执行,可以借助ScheduledThreadPool,核心代码如下

//JDK原生代码片段1 创建线程池
//一个任务一个线程池,且线程池中只配置一个执行线程,即实现单任务单线程执行
//如上,多个任务分别创建多个线程池对象ScheduledExecutorService ,即可实现多任务多线程
private static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

//JDK原生代码片段2 执行定时任务
// 2000代表首次延迟2秒执行
// 30*1000表示执行完成后,30S后再次运行定时任务
// scheduleWithFixedDelay 表示A任务执行完成后,30S后才将下次执行的A任务加入线程池
// scheduleAtFixedRate 表示以A任务开始执行时计时,30S后将下次执行的A任务加入线程队列,此时如果线程池是多个线程,会导致A任务并行执行,慎重
scheduledExecutorService.scheduleWithFixedDelay(() -> {
			try {
				execTask()//此处执行你的定时任务
			} catch (Throwable e) {
				log.error("充分捕获异常,保证定时任务不中断", e);
			}
		}, 2000,30*1000, TimeUnit.MILLISECONDS);

单任务单线程运行,针对@Scheduled,如下两种都是单任务单线程

@Scheduled(initialDelay = 3000, fixedDelay = 30 * 1000)
@Scheduled(cron="${time.cron}")

单任务多线程运行,需配置ScheduleConfig ,且做如下配置

@Scheduled(initialDelay = 3000, fixedRate = 30 * 1000)