一、使用SpringBoot实现定时任务

这个不是重点,就简单的实现一下,至于cron表达式怎么写也不是重点,自行百度即可。

1-1、基于 @Scheduled 注解的方式

import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;@Component@EnableSchedulingpublic class XdxOne {    @Scheduled(cron = "*/1 * * * * ?")    public void testOne(){        System.out.println("one "  + " "+ Thread.currentThread().getName());    }}

1-2、基于SchedulingConfigurer接口实现

import org.springframework.scheduling.Trigger;import org.springframework.scheduling.TriggerContext;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.annotation.SchedulingConfigurer;import org.springframework.scheduling.config.ScheduledTaskRegistrar;import org.springframework.scheduling.support.CronTrigger;import org.springframework.stereotype.Component;import java.util.Date;@Component // 1.主要用于标记配置类,兼备Component的效果。@EnableScheduling // 2.开启定时任务public class XdxTestOne  implements SchedulingConfigurer {    @Override    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {        Runnable task = new Runnable() {            @Override            public void run() {                Thread t = Thread.currentThread();                String name = t.getName();                System.out.println("XdxTestOne=" + name);            }        };        Trigger trigger = new Trigger() {            @Override            public Date nextExecutionTime(TriggerContext triggerContext) {              // 这里我们可以通过去数据库获取cron表达式,从而实现动态                CronTrigger trigger = new CronTrigger("*/3 * * * * ?");                Date nextExec = trigger.nextExecutionTime(triggerContext);                return nextExec;            }        };        scheduledTaskRegistrar.addTriggerTask(task, trigger);    }}

上面两种方式都可以实现定时任务,毫无疑问注解方式实现起来更为舒服。但假如你不想把这个cron表达式写死,对于注解方式我们可能无可奈何(也可能是我没有找到方法)。但是对于接口的方式,我们可以在设置的时候去数据库获取,这样就实现了动态。

接口方式的定时任务每次执行的时候,都会去执行那个获取cron的方法。

二、异步实现

上面只是简单的实现了定时任务,一般来说也没有什么问题,但是上面的方式是一个线程挨个执行定时任务,这就会导致比如你某个线程是1s执行一次,但是你另外一个定时任务执行一次需要10min,那么你的这个定时任务就会被阻塞。

一般来说可能也不重要,因为只要最后执行就好了,但有时却是致命的,比我在工作中有一个定时任务是及时去同步数据来处理,这个时候阻塞了就是致命的。因此我们需要开启异步执行,也就是多线程执行,这样你一个定时任务阻塞了,还有另外的线程去执行我们的定时任务。

2-1、对于使用@Scheduled注解方式实现异步

我们可以使用 @Async 注解实现异步(异步方法使用注解@Async的返回值只能为void或者Future),把@Async加在类或者方法上面,然后还需要一个 @EnableAsync来开启异步。

@EnableAsync可以加在启动类上面这样可以直接开启所有的异步,也可以单独加在每个类上面。

2-1-1:版本差异

springBoot2.0 和 springBoot2.2 默认的线程池是不一样的,2.0默认线程池每开启一个新的任务都是新开一个线程的。2.2默认线程池有8个。

如果你的定时任务比较少,并且执行时间比较短其实上面两种都没啥关系。但是如果定时任务多且慢,那么2.0每次创建一个线程可能导致JVM挂掉,而2.2只有8个线程也会满足不了,会导致任务等待。

2-1-2:自定义线程池

创建一个线程池:

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;@Configuration@EnableAsyncpublic class AsyncConfig {    @Bean(name = "taskExecutor")    public ThreadPoolTaskExecutor asyncExecutor() {        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();        // 核心线程数        executor.setCorePoolSize(10);        // 最大线程数        executor.setMaxPoolSize(50);        // 队列最大长度        executor.setQueueCapacity(1000);        // 线程池维护线程所允许的空闲时间        executor.setKeepAliveSeconds(100);        // 线程前缀        executor.setThreadNamePrefix("AsyncExecutorThread-");        // 线程池对拒绝任务(无线程可用)的处理策略        executor.setRejectedExecutionHandler(new CallerRunsPolicy());        executor.initialize();        return executor;    }}

我们创建了上面的线程池后,所有的任务都将使用这个线程池里面的线程(可以通过输出线程名查看)

但是如果我们有多个线程池的时候,这个时候我们可以使用 @Async(“name”) name就是线程池的名字,没有写name的时候默认使用bean为taskExecutor 的线程池。

2-2、对于使用接口的方式实现异步

而对于使用注解的定时任务,如果你没有使用@Async注解给它指定线程池(可以理解默认name = taskExecutor,如果你没有taskExecutor线程池就会使用默认线程池),它也会使用接口里面创建的线程池进行调用。

三、其它

@EnableScheduling注解是开启定时任务的,随便放在那里都可以,只需要一个。


定时线程_SpringBoot定时任务,@Async多线程异步执行相关推荐

  1. 【SpringBoot】“@Async” 实现异步执行任务

    目录 一.开启异步调用方法 二.创建异步执行类 三.调用异步方法 一.开启异步调用方法 在application启动类中,加上@EnableAsync注解,Spring Boot 会自动扫描异步任务. ...

  2. springboot前端长轮询使用多线程异步执行任务

    1.springboot使用多线程任务时bean 不能使用@Autowired注入 可以提供一个外部类去获取bean对象 @Component public class ApplicationProv ...

  3. java定时器阻塞主线程_springboot定时任务线程阻塞踩坑

    场景描述 在使用Springboot整合定时任务,发现当某个定时任务执行出现执行时间过长的情况时会阻塞其他定时任务的执行. 问题定位 后续通过翻查Springboot的文档以及打印日志(输出当前线程信 ...

  4. android 开启一个定时线程_Android 定时任务刷新的多种实现方式

    1.采用Handle与线程的sleep(long)方法 1) 定义一个Handler类,用于处理接受到的Message. Handler handler = new Handler() { publi ...

  5. springboot主线程_springboot中的多线程.md

    1.程序运行时,自动启动: 这在一般的可执行程序里面,当然可以直接在main函数里执行通过代码启动线程.但在springboot中,我们可以使用@PostConstruct注解的方式,让已经注入bea ...

  6. 线程池和任务工厂实现多线程异步运行

    将多个线程在线程池中运行 知识点保温 引用一下微软官网的介绍: 线程池: https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.th ...

  7. 计算机中 什么是同步执行和异步执行?

    1 当您同步执行某项任务时,您将等待它完成,然后再转到另一项任务.当您异步执行某项任务时,您可以在它完成之前转移到另一个任务. 也就是说,在计算机的上下文中,这转化为在另一个"线程" ...

  8. Spring Boot 之异步执行方法

    给方法加上 @Async 注解 package me.deweixu.aysncdemo.service; public interface AsyncService {void asyncMetho ...

  9. js等待异步执行完再执行_Spring Boot 之异步执行方法

    前言: 最近的时候遇到一个需求,就是当服务器接到请求并不需要任务执行完成才返回结果,可以立即返回结果,让任务异步的去执行.开始考虑是直接启一个新的线程去执行任务或者把任务提交到一个线程池去执行,这两种 ...

最新文章

  1. VMware虚拟机提示在该系统上全局禁用了虚拟机打印功能
  2. *.tar.bz2文件解压
  3. MySQL 空间数据库支持入门学习
  4. hive 查看某表字段类型
  5. fpga如何约束走线_如何正确的约束时钟—Vivado优化到关键路径
  6. Unity3D:视物有点眩晕的原因
  7. javascrip --- 构造函数的继承
  8. OpenCL的安装与配置
  9. [转]ASP中ActiveX控件的内嵌及调用
  10. 听飞狐聊JavaScript设计模式系列07
  11. [LeetCode] NO. 242 Valid Anagram
  12. nosql第一章课后习题
  13. 摸头GIF在线生成工具 附源码
  14. 百度旋转验证码打码模块,集成鱼刺模块类
  15. 解决pymysql.err.InternalError: (1054, Unknown column '某某某' in 'field list') 的问题
  16. 量化框架backtrader之一文读懂Indicator指标
  17. echart 饼图数据显示
  18. 数据可视化路上——中国地图可视化
  19. Poly定理:学习笔记
  20. 标识别,人脸识别等常用数据集

热门文章

  1. 1024程序员节 | 我敢____,你敢么?Are you ready?
  2. oracle redo 200mb,Oracle的redo log在各场景下的恢复
  3. tika设置文件长度限制_MySQLInnoDB某些你没注意过的限制
  4. android获取版本号报错,Android开发:获取安卓App版本号的方法步骤
  5. matlab cell转数组_MATLAB批量修改文件名
  6. java timer schedule_java怎么再次设置Timer的schedule???
  7. Elasticsearch7.15.2 ik中文分词器 定制化分词器之扩展词库(远程)
  8. 集合判断哪非空 、2个集合取交集/并集/差集
  9. Seata 的AT模式需求实战_04
  10. Linux和Windows互传文件可视化工具lrzsz的安装和使用