1.1 同一任务的同步执行(下次任务执行将在本次任务执行完毕后的下一次配置时间开始)
1.2 同一任务的异步执行(下次任务将在下一个配置时间开始,不等待当前任务执行完毕)
在任务运行的时候遇到问题,定时任务没15分钟执行一次,在上一次任务超过下一次任务的开始时间后才运行结束,那么下一次任务就直接跳过,到下下次的任务的时间点到达后才会执行,这就会导致部分任务没有执行,所以需要多个任务并发执行才可以。
2.1 多任务并发执行
首先,要想使用@Scheduled
注解,首先要在启动类上添加注解@EnableScheduling
@SpringBootApplication(scanBasePackages = {"com.redis.example.demo"})
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2.2 添加任务线程池配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
/**
*
* @author xuleyan
* @version BeanConfig.java, v 0.1 2020-09-09 9:01 下午
*/
@Configuration
@EnableAsync
public class ScheduleConfig {
@Bean("taskScheduler")
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(2);
return taskScheduler;
}
}
2.3添加测试类
import com.redis.example.demo.utils.DateTimeUtils;
import com.xuleyan.frame.extend.redis.jedis.JedisTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
*
* @author xuleyan
* @version Test.java, v 0.1 2020-09-09 8:52 下午
*/
@Service
@Slf4j
@EnableAsync
public class MysqlSchedule {
/**
* 异步多线程执行任务
*/
@Async("taskScheduler")
@Scheduled(cron = "0/3 0/1 * * * ?")
public void scheduler() {
String start = DateTimeUtils.format(new Date(), DateTimeUtils.NORMAL_DATETIME_PATTERN);
log.info("开始同步任务: date = {}", start);
jedisTemplate.set("startTime", start);
try {
Thread.sleep(15000);
log.info("sleep 15s");
} catch (InterruptedException e) {
e.printStackTrace();
}
String end = DateTimeUtils.format(new Date(), DateTimeUtils.NORMAL_DATETIME_PATTERN);
log.info("结束同步任务: date = {}", end);
}
}
可以看到两个线程并发的执行,可以实现任务的无缝连接。