java定时任务实现的几种方式(Timer、Spring Task、Quartz)

java定时任务实现的几种方式(Timer、Spring Task、Quartz)

Timer

JDK自带的Timer类,允许调度一个TimerTask任务。

 

Demo:

/**
 * Timer测试类
 */
public class TimerDemo { public static void main(String[] args) { // 创建定时器 Timer timer = new Timer(); // 添加调度任务 // schedule(TimerTask task, Date time); 特定时间 time 执行 // timer.schedule(new MyTask(), new Date(System.currentTimeMillis() + 1000)); // schedule(TimerTask task, long delay); //延迟 delay毫秒 执行 task // timer.schedule(new MyTask(), 1000); // schedule(TimerTask task, long delay, long period) 延迟 delay毫秒 执行并每隔 period毫秒 执行一次 // timer.schedule(new MyTask(), 1000, 5000); // schedule(TimerTask task, Date time, long period); 特定时间 time 执行并每隔 period毫秒 执行一次 timer.schedule(new MyTask(), new Date(System.currentTimeMillis() + 1000), 5000); } }

 

/**
 * 具体执行的任务
 */
public class MyTask extends TimerTask { /** * The action to be performed by this timer task. */ public void run() { System.out.println("执行时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } }

 

Spring Task:

Spring3.0以后自主开发的定时任务工具Spring Task,支持线程池,可以高效处理许多不同的定时任务,除spring相关的包外不需要额外的包,支持注解和配置文件两种形式。 但不能处理过于复杂的任务 。

基于配置的Demo:

定时任务类:

/**
 * spring执行任务的类
 */
public class SpringTask { public void show1() { System.out.println("show1:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } public void show2() { System.out.println("show2:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } }

配置文件spring-schedule.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> <bean id="springTask" class="com.zy.springtask.SpringTask"></bean> <!--注册调度任务--> <task:scheduled-tasks> <!--延迟1秒 执行任务--> <!--<task:scheduled ref="springTask" method="show1" fixed-delay="1000" />--> <!--固定速度3秒 执行任务--> <!--<task:scheduled ref="springTask" method="show2" fixed-rate="3000" />--> <!-- 使用cron表达式 指定触发时间 spring task 只支持6位的cron表达式 秒 分 时 日 月 星期 --> <task:scheduled ref="springTask" method="show1" cron="1-10 * * ? * *" /> </task:scheduled-tasks> <!--执行器配置--> <task:executor id="threadPoolTaskExecutor" pool-size="10" keep-alive="5"></task:executor> <!--调度器配置--> <task:scheduler id="threadPoolTaskScheduler" pool-size="10"></task:scheduler> </beans>

 

基于注解的Demo:

定时任务类:

/**
 * spring执行任务的类
 */
@Component
public class SpringAnnoTask { @Scheduled(cron = "1-10 * * * * ? ")//每分钟的1-10秒每秒执行一次 public void show1() { System.out.println("show1:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } @Scheduled(cron = "0/10 * * * * ? ")//每10秒执行一次 public void show2() { System.out.println("show2:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } }

配置文件spring-schedule.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> <!--启用注解--> <task:annotation-driven></task:annotation-driven> <bean id="springAnnotationTask" class="com.zy.springtask.SpringAnnoTask"></bean> </beans>

 

Quartz

这个就厉害了,这篇文章只能简单介绍个入门案例,如果需要深入研究请自行查看官方文档或者网上找些系列的文章。w3cschool文档

  Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。

 

特点:

  • 强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求;
  • 灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式;
  • 分布式和集群能力,Terracotta 收购后在原来功能基础上作了进一步提升。
  • 另外,作为 Spring 默认的调度框架,Quartz 很容易与 Spring 集成实现灵活可配置的调度功能。

核心元素 :

  • Scheduler: 任务调度器,是实际执行任务调度的控制器。在spring中通过SchedulerFactoryBean封装起来。
  • Trigger :触发器,用于定义任务调度的时间规则,有SimpleTrigger,CronTrigger,DateIntervalTrigger和NthIncludedDayTrigger,其中CronTrigger用的比较多,本文主要介绍这种方式。CronTrigger在spring中封装在CronTriggerFactoryBean中。
  • Calendar:它是一些日历特定时间点的集合。一个trigger可以包含多个Calendar,以便排除或包含某些时间点。
  • Job :任务,是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在JobDataMap实例中。实现Job接口的任务,默认是无状态的,若要将Job设置成有状态的,在quartz中是给实现的Job添加@DisallowConcurrentExecution注解(以前是实现StatefulJob接口,现在已被Deprecated),在与spring结合中可以在spring配置文件的job detail中配置concurrent参数。
  • JobDetail :任务信息,用来描述Job实现类及其它相关的静态信息,如Job名字、关联监听器等信息。在spring中有JobDetailFactoryBean和 MethodInvokingJobDetailFactoryBean两种实现,如果任务调度只需要执行某个类的某个方法,就可以通过MethodInvokingJobDetailFactoryBean来调用。

Trigger触发器 :

  •  SimpleTrigger :在一个指定时间段内执行一次作业任务或是在指定时间间隔内执行多次作业任务;
  •  CronTrigger :基于日历的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用。

 

简单案例:

jar包依赖:

<dependency>
    <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.2.1</version> </dependency>

具体定时任务需要执行的类:

/**
 * 具体执行的任务 实现Job接口
 */
public class MyDemoJob implements Job { public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // 当前时间 System.out.println("执行时间:" + sf.format(new Date())); // 获取Trigger Trigger trigger = jobExecutionContext.getTrigger(); // 通过trigger获取job标识 JobKey jobKey = trigger.getJobKey(); System.out.println("Job's key:" + "name:" + jobKey.getName() + "\tgroup:" + jobKey.getGroup()); // getClass(); System.out.println("Start time : " + sf.format(trigger.getStartTime())); // System.out.println("End time : " + sf.format(trigger.getEndTime()));  } }

 

基础Demo:

/**
 *  基础触发器调度程序
 */
public class BaseScheduler { public static void main(String[] args) { try { // 1. 创建一个JodDetail实例 将该实例与具体要执行的job类 MyDemoJob.class绑定 JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class) // 定义Job类为MyDemoJob类(具体执行定时任务的内容) .withIdentity("myJob", "default") // 定义name/group  .build(); // 2. 定义一个Trigger,10秒后执行 System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); // 2.1 设置开始时间 Date startTime = new Date(); startTime.setTime(startTime.getTime() + 10000L); // 2.2 设置结束时间 // Date endTime = new Date(); //endTime.setTime(endTime.getTime() + 20000L);  Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "default")// 定义名字和组  .startAt(startTime) //.endAt(endTime) .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever()) // 上面这句的意思是 这个定时器每5秒执行一次 直到山峰没有棱角 河水不再流 详细使用请查看withSchedule的参数设置  .build(); // 3. 创建scheduler 从StdSchedulerFactory工厂中获取 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 4. 将jobDetail和trigger加入这个调度(注册 任务详情和触发器)  scheduler.scheduleJob(jobDetail, trigger); // 5. 启动scheduler  scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } }

 

基于SimpleTrigger的Demo:

/**
 * SimpleTrigger 简单触发器调度程序
 */
public class SimpleTriggerScheduler { public static void main(String[] args) { try { // 1. 创建一个JodDetail实例 JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class) .withIdentity("myJob") .build(); // 2. 定义一个Trigger Date startTime = new Date(); startTime.setTime(startTime.getTime() + 5000L); SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() .withIdentity("myTrigger", "group1")// 定义名字和组  .startAt(startTime) .build(); // 3. 创建scheduler Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 4. 将jobDetail和trigger加入这个调度(注册 任务详情和触发器)  scheduler.scheduleJob(jobDetail, trigger); // 5. 启动scheduler  scheduler.start(); } catch (Exception e) { e.printStackTrace(); } } }

 

基于CronTrigger的Demo:

/**
 * CronTrigger 基于Cron表达式的触发器调度程序
 */
public class CronTriggerScheduler { public static void main(String[] args) { try { // 1. 创建一个JodDetail实例 JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class) .withIdentity("myJob") // 定义name/group  .build(); // 2. 定义一个Trigger 使用Cron表达式来控制运行 CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger() .withIdentity("myTrigger", "group1") .withSchedule( //定义任务调度的时间间隔和次数  CronScheduleBuilder .cronSchedule("0/10 * * * * ? ")//每10秒运行一次  ) .build(); // 3. 创建scheduler SchedulerFactory sfact = new StdSchedulerFactory(); Scheduler scheduler = sfact.getScheduler(); // 4. 将jobDetail和trigger加入这个调度(注册 任务详情和触发器)  scheduler.scheduleJob(jobDetail, trigger); // 5. 启动scheduler  scheduler.start(); } catch (Exception e) { e.printStackTrace(); } } }

 

Spring整合Quartz的简单案例

 

PS:Cron表达式介绍

Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:

(1)Seconds Minutes Hours DayofMonth Month DayofWeek Year

(2)Seconds Minutes Hours DayofMonth Month DayofWeek

 

各个字段的含义:

字段允许值允许的特殊字符
秒(Seconds)0~59的整数, - * /    四个字符
分(Minutes0~59的整数, - * /    四个字符
小时(Hours0~23的整数, - * /    四个字符
日期(DayofMonth1~31的整数(但是你需要考虑你月的天数),- * ? / L W C     八个字符
月份(Month1~12的整数或者 JAN-DEC, - * /    四个字符
星期(DayofWeek1~7的整数或者 SUN-SAT (1=SUN), - * ? / L C #     八个字符
年(可选,留空)(Year1970~2099, - * /    四个字符

 

 

 

 

 

 

 

 

 

 

每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:

(1)*:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件。

(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。
例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。 (3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次 (4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次. (5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。 (6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。 (7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。
例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;
如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。 (8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。 (9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

 

posted @ 2017-08-09 02:18 青衫仗剑 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 答:Java实现定时任务方式有三种:1.使用java.util.Timer类;2.使用java.util.concurrent.ScheduledThreadPoolExecutor类;3.使用Quartz框架。 ### 回答2: Java实现定时任务有以下几种方式: 1. Timer类:Java提供了Timer类来帮助实现定时任务。通过创建一个Timer实例和一个TimerTask实例,可以设定任务的执行时间和间隔时间,然后使用Timer的schedule()方法来启动任务。 2. ScheduledExecutorService接口:Java提供了ScheduledExecutorService接口来实现定时任务。该接口继承自ExecutorService接口,可以使用ThreadPoolExecutor来实现。通过调用schedule()方法,可以设定任务的执行时间和间隔时间,然后将任务提交给ScheduledExecutorService。 3. cron表达式:在Java中,还可以使用cron表达式来实现定时任务。cron表达式是一种用来设置时间的字符串格式,通过设置不同的字段,可以实现精确到秒的定时任务。可以使用Quartz框架等工具来解析和执行cron表达式。 4. Spring框架的@Scheduled注解:如果在Spring框架中开发应用,可以使用@Scheduled注解来实现定时任务。通过在方法上标记@Scheduled注解,并设置相应的时间表达式,可以让方法在指定的时间间隔内执行。 需要注意的是,以上方式都是基于Java定时任务实现,可以根据具体需求选择最合适的方式实现定时任务。 ### 回答3: 在Java中,我们可以使用以下几种方式实现定时任务。 1. Timer类:Java中的Timer类是一个简单的定时器工具,它可以通过创建Timer对象并调用其schedule()方法来设置定时任务。该方法可以指定一个任务(实现TimerTask接口的类)和一个延迟时间,然后在延迟时间之后开始执行定时任务。 2. ScheduledExecutorService接口:Java中的ScheduledExecutorService接口是一个在指定的延迟时间之后或者以固定的时间间隔重复执行任务的调度器。可以使用Executors工厂类的newScheduledThreadPool()方法创建ScheduledExecutorService对象,并使用其schedule()方法来设置定时任务。 3. Quartz框架:Quartz是一个功能强大且灵活的开源定时任务调度框架。它提供了许多高级的调度功能,如任务的并发执行、动态调度、集群支持等。使用Quartz框架,我们可以通过配置定时任务的详细信息(如触发器、调度器等),然后让框架来管理和执行定时任务。 4. SpringTaskSpring框架提供了一个简单的任务调度器,可以通过配置的方式实现定时任务。在Spring的配置文件中,我们可以使用<task:scheduler>和<task:scheduled>标签来定义定时任务的调度器和具体的定时任务方法。 综上所述,Java实现定时任务方式有多种选择。根据需求的复杂性和灵活性的要求,我们可以选择适合的方式实现定时任务

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值