本文共 2723 字,大约阅读时间需要 9 分钟。
Task定时任务默认都是使用单线程执行的,如果定时任务有很多的话,那么可能会导致很多任务无法按时准确执行,示例如下:
import java.text.SimpleDateFormat;import java.util.Date;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;@Componentpublic class TaskTest { private final Logger log = LoggerFactory.getLogger(TaskTest02.class); //输出时间格式 private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:sss"); @Scheduled(cron = "0/15 * * * * ? ") private void sayHello(){ String dateTime = format.format(new Date()); log.info("{} 向宇宙发出了一声问候: Hello World!", dateTime); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } @Scheduled(cron = "0/16 * * * * ? ") private void sayHello2(){ String dateTime = format.format(new Date()); log.info("{} 向宇宙发出了一声问候: 你好,世界", dateTime); }}
当sayHello()方法执行的时候,因为长时间占用任务执行线程,导致sayHello2()被迫向后延时执行,如图:
添加以下代码块,可放置在任意一个类中,整个工程只需要添加一个即可
@Beanpublic TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); // 设置scheduler执行线程为3个 scheduler.setPoolSize(3); return scheduler;}
添加一个配置类即可,定时任务类或方法不用做任何改变
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.TaskScheduler;import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;/** * @描述: 多线程执行定时任务 * @日期 2019年5月28日 */@Configurationpublic class TaskConfig { /** * @描述: 所有的定时任务都放在一个线程池中,定时任务启动时使用不同的线程 * @return * @日期 2019年5月28日 */ @Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); // 设置scheduler执行线程为3个 scheduler.setPoolSize(3); return scheduler; }}
添加一个配置类即可(实现SchedulingConfigurer接口),定时任务类或方法不用做任何改变
import java.util.concurrent.Executors;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.SchedulingConfigurer;import org.springframework.scheduling.config.ScheduledTaskRegistrar;/** * @描述: 多线程执行定时任务 * @日期 2019年5月27日 */@Configurationpublic class SchedulingConfig implements SchedulingConfigurer { /** * @描述: 所有的定时任务都放在一个线程池中,定时任务启动时使用不同的线程 * @param taskRegistrar * @日期 2019年5月27日 */ @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { //设定一个定时任务线程池,数量为3 taskRegistrar.setScheduler(Executors.newScheduledThreadPool(3)); }}
可以看到两个定时任务已经分别由不同的线程执行了
转载于:https://blog.51cto.com/1197822/2401581