定时线程_SpringBoot定时任务,@Async多线程异步执行

一、使用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、对于使用接口的方式实现异步

e8fa3ba3f369bcbec25bef765196797b.png

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

三、其它

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


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/530351.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql怎么把datetime类型转换_mysql怎样实现time转datetime

mysql实现time转datetime的方法:使用在sql语句中【FROM_UNIXTIME(时间值)】,代码为【insert into test(time) values(FROM_UNIXTIME(%d))",time(NULL)】。mysql实现time转datetime的方法:FROM_UNIXTIME(time(NULL))将liunx系统的time_t类…

SpringBoot入门二

参考Spring Boot Starters - 御坂研究所 创建自己的starter starter是依赖的一种synthesize&#xff08;合成&#xff09;。 starter会把需要用到的依赖全部包含进来&#xff0c;避免开发者自己手动引入依赖。 starter的逻辑 pom.xml<parent><groupId>org.spri…

Tomcat入门

一&#xff0c;tomcat启动 双击startup.bat,如果出现一闪而过的情况&#xff0c;在文件的末尾添加pause&#xff0c;就可以看到环境变量设置的路径是否正确 如果无法在电脑的高级系统设置中设置环境变量&#xff0c;可以在setclasspath.bat中设置环境变量 set JAVA_HOMEC:\P…

线程组的概念

一&#xff0c;线程组和线程的结构&#xff1a;树形结构 每个Thread必然存在于一个ThreadGroup中&#xff0c;Thread不能独立于ThreadGroup存在。 执行main()方法线程的名字是main 如果在new Thread时没有显式指定&#xff0c;那么默认将父线程&#xff08;当前执行new Threa…

delphi7 mysql控件_Delphi7连接MySql数据库-DBGrid控件显示数据

一个简单的Delphi7小程序&#xff0c;使用MySql数据库做简单查询&#xff0c;用DBGrid控件显示结果&#xff0c;实现过程如下&#xff1a;(1)在MySql中新建demouser表&#xff0c;插入记录用于测试。(2)在Delphi7中新建项目。(3)在From中添加组件。组件Panel&#xff1a;pnl1组…

filtic函数 matlab_matlab filtic 函数应用 filter 解差分方程 dft 函数

matlab filtic 函数应用 filter 解差分方程 dft 函数一、 解差分方程说明都在代码注释里面了%这里要利用filtic函数 为滤波器的直接II型实现选择初始条件%求解查分方程 y(n) - 0.4y(n-1) - 0.45y(n-2) 0.45x(n) 0.4x(n-1) - x(n-2)%y(-1) 0 y(-2) 1 x(-1) 1 x(-2) 2%x(n)…

rabbitmq进阶一

上一篇文章有讲到rabbitmq的安装、web管理端和springboot简单集成rabbitmq 本文重点介绍rabbitmq相关api的使用 按照官网常用的五种模式的顺序&#xff1a;HelloWorld、Work queues、Publish/Subscribe、Routing、Topics 模式简单介绍 HelloWorld 一个生产者&#xff0c;一…

mysql一直copying to tmp table_mysql提示Copying to tmp table on disk

网站运行的慢了&#xff0c;查找原因是Copying to tmp table on disk那怎么解决这个问题呢解决一例最近常常碰到网站慢的情况&#xff0c;登陆到后台&#xff0c;查询一下 /opt/mysql/bin/mysqladmin processlist;发现一个查询状态为&#xff1a; Copying to tmp table 而且此查…

idea cloud bootstrap是啥_application.yml与bootstrap.yml的区别

Spring Boot 默认支持 properties(.properties) 和 YAML(.yml .yaml ) 两种格式的配置文件&#xff0c;yml 和 properties 文件都属于配置文件&#xff0c;功能一样。Spring Cloud 构建于 Spring Boot 之上&#xff0c;在 Spring Boot 中有两种上下文&#xff0c;一种是 bootst…

元数据解决分表不可 mysql_MySQL InnoDB技术内幕:内存管理、事务和锁

前面有多篇文章介绍过MySQL InnoDB的相关知识&#xff0c;今天我们要更深入一些&#xff0c;看看它们的内部原理和机制是如何实现的。一、内存管理我们知道&#xff0c;MySQl是一个存储系统&#xff0c;数据最后都写在磁盘上。我们以前也提到过&#xff0c;磁盘的速度特别是大容…

navicat for mysql 13_Navicat for MySQL下载

Navicat for MySQL 是一套管理和开发 MySQL 或 MariaDB 的理想解决方案。它使你以单一程序同时连接到 MySQL 和 MariaDB。这个功能齐备的前端软件为数据库管理、开发和维护提供了直观而强大的图形界面。它提供了一组全面的工具给 MySQL 或MariaDB 新手&#xff0c;同时给专业人…

spring兼容mysql_springboot 最新版本支持 mysql6.0.6吗

缥缈止盈1.首先在pom文件中加入下列依赖,一个使用jpa所需依赖,一个连接MySQL使用的依赖:mysqlmysql-connector-javaorg.springframework.bootspring-boot-starter-data-jpa 123456789102.在配置文件中添加datasource配置和jpa配置,在mysql中已经提前创建了一个名为db_test的数据…

java虚拟机内存监控_java虚拟机内存监控工具jps,jinfo,Jstack,jstat,jmap,jhat使用...

将会打印出很多jvm运行时参数信息&#xff0c;由于比较长这里不再打印出来&#xff0c;可以自己试试&#xff0c;内容一目了然Jstack(Stack Trace for Java)&#xff1a;JVM堆栈跟踪工具jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息&#xff0c;如…

idea 调试java技巧_IDEA 调试Java代码的两个技巧

本文介绍两个使用IDEA 调试Java代码的两个技巧&#xff1a;修改变量值使用RuntimeException终止代码执行修改变量值在Java代码调试过程中&#xff0c;我们可以修改变量值&#xff0c;使其达到走指定分支的目的&#xff0c;或者使其满足某个条件。我们以给变量beanName赋值为例&…

java免检异常_java-异常

java提供了异常处理机制&#xff1a;程序运行受阻时候的处理方式。1、异常分类Error&#xff1a;系统错误&#xff0c;由java虚拟机抛出&#xff0c;很少发生&#xff1b;免检异常RuntimeException&#xff1a;程序设计错误&#xff0c;通常由java虚拟机抛出&#xff1b;免检异…

java编程需要数学知识吗_初学Java编程,需要英语和数学基础吗?

原标题&#xff1a;初学Java编程&#xff0c;需要英语和数学基础吗&#xff1f;“学习Java编程英语和数学是必备条件吗&#xff1f;”很多Java零基础学习或者转型IT行业的都会有这样的疑问&#xff0c;其实刚开始学习Java编程是不需要太高深的数学和英语基础的。刚开始学习Java…

java简单数据结构_图解Java常用数据结构

最近在整理数据结构方面的知识, 系统化看了下 Java 中常用数据结构, 突发奇想用动画来绘制数据流转过程.主要基于 jdk8, 可能会有些特性与 jdk7 之前不相同, 例如 LinkedList LinkedHashMap 中的双向列表不再是回环的.HashMap 中的单链表是尾插, 而不是头插入等等, 后文不再赘叙…

java const关键字_const关键字:终于拥有真正的常量声明语句

你好&#xff0c;今天大叔想和你唠扯唠扯 ES6 新增的关键字 —— const。在说 const 关键字之前&#xff0c;大叔先和你唠唠大叔自己对 const 的感受 —— JavaScript 尼玛终于可以声明真正的常量啦&#xff01;大叔为啥会发出这样滴感叹&#xff1f;实在是“天下苦秦久矣”呀~…

workerman高并发异步mysql_workerman怎么实现高并发

并发概念太模糊&#xff0c;这里以两种可以量化的指标并发连接数和并发请求数来说明。并发连接数是指服务器当前时刻一共维持了多少TCP连接&#xff0c;而这些连接上是否有数据通讯并不关注。 (推荐学习&#xff1a; workerman教程)例如一台消息推送服务器上可能维持了百万的设…

checkout 撤销修改_Git的4个阶段的撤销更改

虽然git诞生距今已有12年之久&#xff0c;网上各种关于git的介绍文章数不胜数&#xff0c;但是依然有很多人(包括我自己在内)对于它的功能不能完全掌握。以下的介绍只是基于我个人对于git的理解&#xff0c;并且可能生编硬造了一些不完全符合git说法的词语。目的只是为了让git通…