admin管理员组

文章数量:1794759

SpringBoot使用Schedule实现异步执行定时任务(多线程)

SpringBoot使用Schedule实现异步执行定时任务(多线程)

Scheduling 本身是单线程机制,要想多个定时任务并行执行,需要使用 @Async 注解采用异步执行方式。

在Spring中,基于@Async标注的方法,称之为异步方法,这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

启动类添加@EnableScheduling开启定时任务,添加@EnableAsync开启异步支持

@SpringBootApplication @EnableWebMvc @EnableAsync @EnableScheduling @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) public class RiverownerservicewzApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(RiverownerservicewzApplication.class, args); } }

创建定时任务实例

/** - @author wjw - @version 1.0 - @date 2020-06-29 12:13 */ @Component public class test { private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Async @Scheduled(cron = "0 0/1 * * * ? ") public void test1() { System.out.println("第一个定时任务开始:" + format.format(new Date())); try { Thread.sleep(10000); System.out.println("第一个定时任务结束:" + format.format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } @Async @Scheduled(cron = "0 0/1 * * * ? ") public void test2() { System.out.println("第二个定时任务开始:" + format.format(new Date())); try { Thread.sleep(10000); System.out.println("第二个定时任务结束:" + format.format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } } }

执行结果

第二个定时任务开始:2020-06-29 13:47:00 第一个定时任务开始:2020-06-29 13:47:00 第一个定时任务结束:2020-06-29 13:47:10 第二个定时任务结束:2020-06-29 13:47:10

Async 在未指定线程池时,使用的是springBoot内置的线程池,那如何指定使用自定义的线程池呢?下面是配置Async异步执行使用自定义线程池的步骤。

自定义线程池 /** * @author wjw * @version 1.0 * @date 2020-03-02 10:47 */ @Configuration @EnableAsync public class ExecutorConfig { private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class); @Bean(name = "MyThreadPool") public Executor MyThreadPool() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(30);//表示线程池核心线程,正常情况下开启的线程数量。 executor.setQueueCapacity(500); //配置队列大小 executor.setMaxPoolSize(50);//当核心线程都在跑任务,还有多余的任务会存到此处。 executor.setKeepAliveSeconds(60);//非核心线程的超时时长,超长后会被回收。 executor.setThreadNamePrefix("MyThreadPool-");//配置线程池前缀 //用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean executor.setWaitForTasksToCompleteOnShutdown(true); executor.setRejectedExecutionHandler((Runnable r, ThreadPoolExecutor exe) -> { logger.warn("MyThreadPool-当前任务线程池队列已满!"); });//配置拒绝策略 executor.initialize();//初始化线程池。 return executor; } }

创建定时任务示例,只需在Async注解后指定线程池名即可

@Async("MyThreadPool") @Scheduled(cron = "0 0/1 * * * ? ") public void test1() { System.out.println("第一个定时任务开始:" + format.format(new Date())); try { Thread.sleep(10000); System.out.println("第一个定时任务结束:" + format.format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } }

 

本文标签: 多线程SpringBootschedule