平常求赞,感谢老板。欢迎关注公众号:实际上是白羊。干货持续更新中......java
在作业务时总会有这样的场景:在特定时间去执行某些逻辑。这其实就是定时任务的应用场景,好比:须要每个月一日给用户发上月数据总结等场景。spring
实现定时任务的技术不少多线程
开启定时任务,可标注在启动类或者任何配置类上(能扫描到对象上均可以)并发
配置具体的任务执行规则,可标注在能被扫描的类的方法上,属性有:app
定时任务的场景:延迟执行、必定频率执行、指定时间执行框架
这里的cron表达式即为了描述任务执行的时间规则。cron由6-7个元素组成,他们之间使用空格来分割,以此表明:异步
除了上面的数字元素值还有下面几个特殊的元素值:spring-boot
了解了上面的表达式规则就能够写出知足条件的cron表达式了,建议多设计几个场景练习下ui
若是就按上面的配置写好任务A(fixedRate=2000)和任务B(fixedRate=3000)直接启动执行的话,会存在如下问题:this
上面的问题都不能让咱们的任务按照各自规定的执行计划去执行,归根到底仍是全部的任务都在一个线程里进行,因此作不到异步的并发执行,那这是就能够经过多线程来实现各个任务之间异步的并发执行
这里咱们可使用Spring的@Async注解来实现异步
SpringBoot一样支持@Async来实现异步(增长了自动配置可直接使用)
标注在启动类或配置类上,表是开启异步
可标注在类上(能被spring容器扫描到的类上)或方法上
标注在类上则这个类里的方法都被表示为异步
须要返回值:
@Async public Future<String> doTaskOne() throws Exception { return new AsyncResult<>("任务一完成"); }
使用@Async来实现异步,其底层仍是使用了多线程来进行实现的,那么这个多线程或者线程池是在哪里设置或配置的呢?咱们都直到SpringBoot加入了大量的自动配置,咱们在spring-boot-autoconfigure包下面能够找到task包下的TaskExecutionAutoConfiguration类中:
@Lazy @Bean(name = { APPLICATION_TASK_EXECUTOR_BEAN_NAME, AsyncAnnotationBeanPostProcessor.DEFAULT_TASK_EXECUTOR_BEAN_NAME }) @ConditionalOnMissingBean(Executor.class) //这个注解的意思:当在容器中没有发现Executor这个类则会加载这个bean,能够理解为此处为默认缺省对象 //返回的是一个spring为咱们提供的线程池 public ThreadPoolTaskExecutor applicationTaskExecutor(TaskExecutorBuilder builder) { return builder.build(); }
找到TaskExecutorBuilder:
@Bean @ConditionalOnMissingBean public TaskExecutorBuilder taskExecutorBuilder() { TaskExecutionProperties.Pool pool = this.properties.getPool(); TaskExecutorBuilder builder = new TaskExecutorBuilder(); builder = builder.queueCapacity(pool.getQueueCapacity()); builder = builder.corePoolSize(pool.getCoreSize()); builder = builder.maxPoolSize(pool.getMaxSize()); builder = builder.allowCoreThreadTimeOut(pool.isAllowCoreThreadTimeout()); builder = builder.keepAlive(pool.getKeepAlive()); builder = builder.threadNamePrefix(this.properties.getThreadNamePrefix()); builder = builder.customizers(this.taskExecutorCustomizers.orderedStream()::iterator); builder = builder.taskDecorator(this.taskDecorator.getIfUnique()); return builder; }
这里的properties是在TaskExecutionProperties加载进来的,默认的参数:
private int queueCapacity = Integer.MAX_VALUE; private int coreSize = 8; private int maxSize = Integer.MAX_VALUE; private boolean allowCoreThreadTimeout = true;
根据下面可知,也能够从yml/properties文件中自定义配置
@ConfigurationProperties("spring.task.execution")
除了上面的方法咱们还能够定义本身的Bean来替换默认缺省Bean,根据@ConditionalOnMissingBean(Executor.class)可知,咱们只须要在配置类里加上:
@Bean public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(核心线程数量); executor.setMaxPoolSize(最大线程数量); executor.setQueueCapacity(任务队列大小); executor.initialize(); return executor; }
根据上面的介绍,要实现异步的定时任务就能够展开,任务方法上面加上@Async来实现
点个赞啊亲
若是你认为本文对你有帮助,能够「在看/转发/赞/star」,多谢若是你还发现了更好或不一样的想法,还能够在留言区一块儿探讨下
欢迎关注公众号:「实际上是白羊」干货持续更新中......