在几乎所有的项目中,定时任务的使用都是必不可少的,如果使用不当,甚至可能造成资金损失。下面的文章主要介绍在Java中实现定时任务的三种最简单的方法。本文通过示例代码非常详细的介绍了它们,有需要的朋友可以参考一下。
目录
I、Timer II、ScheduledExecutorService III、Spring Task1 I、启动定时任务II、添加定时任务Cron表达式知识扩展:分布式定时任务I、ZSet实现II、Keyspace通知总结
一、Timer
Timer是JAVA自己的定时任务类,实现如下:
公共类MyTimerTask {
公共静态void main(String[] args) {
//定义任务
TimerTask TimerTask=new TimerTask(){
@覆盖
公共无效运行(){
System.out.println('打印当前时间:'新日期());
}
};
//计时器
Timer Timer=new Timer();
//开始执行任务(延迟1000毫秒,每3000毫秒执行一次)
timer.schedule(timerTask,1000,3000);
}
}
Timer 优缺点分析
优点是使用简单,缺点是当添加并执行多个任务时,前面任务的执行用时和异常将影响到后面任务,这边深海建议谨慎使用。
二、ScheduledExecutorService
ScheduledExecutorService也是Java自带的一个类,
它可以实现Timer具备的所有功能,并解决了 Timer类存在的问题。
实现如下:
公共类MyScheduledExecutorService {
公共静态void main(String[] args) {
//按照线程数创建任务队列10。
ScheduledExecutorService ScheduledExecutorService=
executors . newscheduledthreadpool(10);
//执行任务
scheduledexecutorservice . scheduleatfixedrate(()-{
System.out.println('打印当前时间:'新日期());
},1,3,时间单位。秒);//1s后开始执行,每3s执行一次。
}
}
ScheduledExecutorService优缺点分析
优点是,该类是JDK1.5自带的类,使用简单,缺点是该方案仅适用于单机环境。
三、Spring Task
Spring系列框架中Spring框架自带的计时任务,
使用上面两种方式,很难实现某些特定需求,比如每周一执行某任务,但是SpringTask很容易实现。
以SpringBoot为例实现:
1、开启定时任务
在SpringBoot的启动类上声明@EnableScheduling:
@SpringBootApplication
@EnableScheduling //启动计划任务
公共类演示应用程序{
//- -
}
2、添加定时任务
只需用@Scheduled注释对其进行标记,
如果有多个计划任务,您可以创建多个标有@Scheduled的方法。例子如下:
导入org . spring framework . scheduling . annotation . scheduled;
导入org . spring framework . stereotype . component;
@Component //信任这个类来Spring,不能省略。
公共类任务工具{
//添加计划任务
@ scheduled(cron=' 30 40 23 005 ')//cron表达式:每周一23:40:30。
public void doTask(){
System.out.println('我是定时任务~ ');
}
}
Spring Boot启动后,会自动加载并执行预定任务,无需手动操作。
Cron 表达式
Spring任务的实现需要使用cron表达式来声明执行的频率和规则。cron表达式由6位或7位组成(最后一位可以省略),每一位用空格隔开。每一位的含义从左到右如下:
*然后呢?所有数字表示所有时间都匹配。
Cron表情在线生成地址:https://cron.qqe2.com/
知识扩展:分布式定时任务
上面的方法都是关于单机定时任务的实现,如果是分布式环境可以使用 Redis 来实现定时任务。
使用Redis实现延迟任务的方法大体可分为两类:通过 ZSet 的方式和键空间通知的方式。
1、ZSet 实现方式
通过ZSet实现定时任务的思路是将定时任务存储在ZSet集合中,过期时间存储在ZSet的Score字段中。然后,使用无线环路来确定当前时间是否有需要执行的定时任务,如果有,具体实现代码如下:
导入redis . clients . jedis . jedis;
导入实用程序。杰迪苏蒂尔斯;
导入Java . time . instant;
导入Java . util . set;
公共类DelayQueueExample {
private static final String _ KEY=' DelayQueueExample ';
公共静态void main(String[] args)引发InterruptedException {
jedis jedis=jedisutils . get jedis();
30s后执行。
long delayTime=Instant.now().几秒钟(30秒)。get pocket second();
杰迪斯。zad(_ key,delayTime," order _ 1 ");
//继续添加测试数据
杰迪斯。zad(_ key,Instant.now)().几秒钟(2)。getepochsecond(),' order _ 2 ';
杰迪斯。zad(_ key,Instant.now)().几秒钟(2)。getepochsecond(),' order _ 3 ';
杰迪斯。zad(_ key,Instant.now)().几秒钟(7)。getepochsecond(),' order _ 4 ';
杰迪斯。zad(_ key,Instant.now)().几秒钟(10)。getepochsecond(),' order _ 5 ';
//开启定时任务队列
多达利队列(杰迪斯):
}
/**
*定时任务队列消费
* @param jedis Redis(参数杰迪斯重定向器)客户端
*/
公共静态void dodaley队列(jedis jedis)抛出中断异常[
while(true)}
//当前时间
Instant nowInstant=Instant.now():
长负载秒=nowInstant .多秒(-1)。get pocket second();
//上一秒时间
长nowsecond=nowinstant。get pocket second();
//查询当前时间的所有任务
设置数据=jedis。zrangebycore(_ key、lastsecond、now second);
对于(字符串项:日期)}
//消费任务
System.out.println('消费:'项目:
}
//删除已经执行的任务
杰迪斯。zremrangebycore(_ key、lastsecond、now second);
线程。休眠(1000);//每秒查询一次
}
}
}
2、键空间通知
我们可以通过再说一遍的键空间通知来实现定时任务,它的实现思路是给所有的定时任务设置一个过期时间,等到了过期之后,我们通过订阅过期消息就能感知到定时任务需要被执行了,此时我们执行定时任务即可。
默认情况下再说一遍是不开启键空间通知的,需要我们通过配置集通知-按键空间事件前夫;前妻;前男友;前女友的命令手动开启,开启之后定时任务的代码如下:
汇入客户绝地、绝地:
汇入客户名称jedis、jedispubsub:
导入实用程序。视觉样式:
公共类任务示例
public static final string _ topic=' _ _ key event @ 0 _:已过期;//订阅频道名称
public static void main(string[]args)>
绝地武士=绝地风格。get Jedi();
//执行定时任务
dotask(杰迪斯);
}
/**
*订阅过期消息,执行定时任务
* @param jedis Redis(参数杰迪斯重定向器)客户端
*/
公共静态void dotask(jedis jedis)>
//订阅过期消息
jedis . PSU subscribe(新jedispubsub()).
@覆盖
public void onPMessage(字符串模式、字符串通道、字符串消息)
//接收到消息,执行定时任务
System.out.println('收到消息*信息:
}
}、话题
}
}
总结
到此这篇关于Java(Java)实现定时任务最简单的3种方法的文章就介绍到这了,更多相关Java(Java)定时任务实现内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。