`
topzhujia
  • 浏览: 56586 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

在 Java 应用程序中定时执行任务

    博客分类:
  • JAVA
阅读更多

Java 中Timer 类的简洁用法

所有类型的 Java 应用程序一般都需要计划重复执行的任务。企业应用程序需要计划每日的日志或者晚间批处理过程。一个 J2SE或者 J2ME 日历应用程序需要根据用户的约定计划闹铃时间。不过,标准的调度类 Timer 和 TimerTask 没有足够的灵活性,无法支持通常需要的计划任务类型。在本文中,Java 开发人员 Tom White 向您展示了如何构建一个简单通用的计划框架,以用于执行任意复杂的计划任务。
我将把 java.util.Timer 和 java.util.TimerTask 统称为 Java 计时器框架,它们使程序员可以很容易地计划简单的任务(注意这些类也可用于 J2ME 中)。在 Java 2 SDK, Standard Edition, Version 1.3 中引入这个框架之前,开发人员必须编写自己的调度程序,这需要花费很大精力来处理线程和复杂的 Object.wait() 方法。不过,Java 计时器框架没有足够的能力来满足许多应用程序的计划要求。甚至一项需要在每天同一时间重复执行的任务,也不能直接使用 Timer 来计划,因为在夏令时开始和结束时会出现时间跳跃。

本文展示了一个通用的 Timer 和 TimerTask 计划框架,从而允许更灵活的计划任务。这个框架非常简单 ―― 它包括两个类和一个接口 ―― 并且容易掌握。如果您习惯于使用 Java 定时器框架,那么您应该可以很快地掌握这个计划框架(有关 Java 定时器框架的更多信息,请参阅 参考资料)。

计划单次任务
计划框架建立在 Java 定时器框架类的基础之上。因此,在解释如何使用计划框架以及如何实现它之前,我们将首先看看如何用这些类进行计划。

想像一个煮蛋计时器,在数分钟之后(这时蛋煮好了)它会发出声音提醒您。清单 1 中的代码构成了一个简单的煮蛋计时器的基本结构,它用 Java 语言编写:

清单 1. EggTimer 类

 1package org.tiling.scheduling.examples; 
 2

 3import
 java.util.Timer; 
 4import
 java.util.TimerTask; 
 5

 6public class EggTimer 

 7     private final Timer timer = new
 Timer(); 
 8     private final int
 minutes; 
 9

10     public EggTimer(int minutes) 

11         this.minutes =
 minutes; 
12     }
 
13

14     public void start() 

15         timer.schedule(new TimerTask() 

16             public void run() 

17
                 playSound(); 
18
                 timer.cancel(); 
19             }
 
20             private void playSound() 

21                 System.out.println("Your egg is ready!"
); 
22                 // Start a new thread to play a sound 

23             }
 
24         }
, minutes * 60 * 1000); 
25     }
 
26

27     public static void main(String[] args) 

28         EggTimer eggTimer = new EggTimer(2
); 
29
         eggTimer.start(); 
30     }
 
31

32}
 
33




EggTimer 实例拥有一个 Timer 实例,用于提供必要的计划。用 start() 方法启动煮蛋计时器后,它就计划了一个 TimerTask ,在指定的分钟数之后执行。时间到了, Timer 就在后台调用 TimerTask 的 start() 方法,这会使它发出声音。在取消计时器后这个应用程序就会中止。

计划重复执行的任务
通过指定一个固定的执行频率或者固定的执行时间间隔, Timer 可以对重复执行的任务进行计划。不过,有许多应用程序要求更复杂的计划。例如,每天清晨在同一时间发出叫醒铃声的闹钟不能简单地使用固定的计划频率 86400000 毫秒(24 小时),因为在钟拨快或者拨慢(如果您的时区使用夏令时)的那些天里,叫醒可能过晚或者过早。解决方案是使用日历算法计算每日事件下一次计划发生的时间。而这正是计划框架所支持的。考虑清单 2 中的 AlarmClock 实现(有关计划框架的源代码以及包含这个框架和例子的 JAR 文件,请参阅 参考资料):

清单 2. AlarmClock 类

 1package org.tiling.scheduling.examples; 
 2

 3import
 java.text.SimpleDateFormat; 
 4

 5import
 java.util.Date; 
 6

 7import
 org.tiling.scheduling.Scheduler; 
 8import
 org.tiling.scheduling.SchedulerTask; 
 9import
 org.tiling.scheduling.examples.iterators.DailyIterator; 
10

11public class AlarmClock 

12

13     private final Scheduler scheduler = new
 Scheduler(); 
14     private final SimpleDateFormat dateFormat =
 
15         new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS"
); 
16     private final int
 hourOfDay, minute, second; 
17

18     public AlarmClock(int hourOfDay, int minute, int second) 

19         this.hourOfDay =
 hourOfDay; 
20         this.minute =
 minute; 
21         this.second =
 second; 
22     }
 
23

24     public void start() 

25         scheduler.schedule(new SchedulerTask() 

26             public void run() 

27
                 soundAlarm(); 
28             }
 
29             private void soundAlarm() 

30                 System.out.println("Wake up! " +
 
31                     "It's " + dateFormat.format(new
 Date())); 
32                 // Start a new thread to sound an alarm 

33             }
 
34         }
new DailyIterator(hourOfDay, minute, second)); 
35     }
 
36

37     public static void main(String[] args) 

38         AlarmClock alarmClock = new AlarmClock(700
); 
39
         alarmClock.start(); 
40     }
 
41}
 
42

43



注意这段代码与煮蛋计时器应用程序非常相似。 AlarmClock 实例拥有一个 Scheduler (而不是 Timer )实例,用于提供必要的计划。启动后,这个闹钟对 SchedulerTask (而不是 TimerTask )进行调度用以发出报警声。这个闹钟不是计划一个任务在固定的延迟时间后执行,而是用 DailyIterator 类描述其计划。在这里,它只是计划任务在每天上午 7:00 执行。下面是一个正常运行情况下的输出:


Wake up! It's 24 Aug 2003 07:00:00.023
Wake up! It's 25 Aug 2003 07:00:00.001
Wake up! It's 26 Aug 2003 07:00:00.058
Wake up! It's 27 Aug 2003 07:00:00.015
Wake up! It's 28 Aug 2003 07:00:00.002
...



DailyIterator 实现了 ScheduleIterator ,这是一个将 SchedulerTask 的计划执行时间指定为一系列 java.util.Date 对象的接口。然后 next() 方法按时间先后顺序迭代 Date 对象。返回值 null 会使任务取消(即它再也不会运行)―― 这样的话,试图再次计划将会抛出一个异常。清单 3 包含 ScheduleIterator 接口:

清单 3. ScheduleIterator 接口

1package org.tiling.scheduling; 
2

3import
 java.util.Date; 
4

5public interface ScheduleIterator 

6     public
 Date next(); 
7}
 






DailyIterator 的 next() 方法返回表示每天同一时间(上午 7:00)的 Date 对象,如清单 4 所示。所以,如果对新构建的 next() 类调用 next() ,那么将会得到传递给构造函数的那个日期当天或者后面一天的 7:00 AM。再次调用 next() 会返回后一天的 7:00 AM,如此重复。为了实现这种行为, DailyIterator 使用了 java.util.Calendar 实例。构造函数会在日历中加上一天,对日历的这种设置使得第一次调用 next() 会返回正确的 Date 。注意代码没有明确地提到夏令时修正,因为 Calendar 实现(在本例中是 GregorianCalendar )负责对此进行处理,所以不需要这样做。

清单 4. DailyIterator 类

 1package org.tiling.scheduling.examples.iterators; 
 2

 3import
 org.tiling.scheduling.ScheduleIterator; 
 4

 5import
 java.util.Calendar; 
 6import
 java.util.Date; 
 7

 8/** */
/** 
 9
* A DailyIterator class returns a sequence of dates on subsequent days 
10
* representing the same time each day. 
11*/
 
12public class DailyIterator implements ScheduleIterator 

13     private final int
 hourOfDay, minute, second; 
14     private final Calendar calendar =
 Calendar.getInstance(); 
15

16     public DailyIterator(int hourOfDay, int minute, int second) 

17         this(hourOfDay, minute, second, new
 Date()); 
18     }
 
19

20     public DailyIterator(int hourOfDay, int minute, int second, Date date) 

21         this.hourOfDay =
 hourOfDay; 
22         this.minute =
 minute; 
23         this.second =
 second; 
24
         calendar.setTime(date); 
25
         calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); 
26
         calendar.set(Calendar.MINUTE, minute); 
27
         calendar.set(Calendar.SECOND, second); 
28         calendar.set(Calendar.MILLISECOND, 0
); 
29         if (!calendar.getTime().before(date)) 

30             calendar.add(Calendar.DATE, -1
); 
31         }
 
32     }
 
33

34     public Date next() 

35         calendar.add(Calendar.DATE, 1
); 
36         return
 calendar.getTime(); 
37     }
 
38

39}
 
40</s
分享到:
评论

相关推荐

    在 Java 应用程序中定时执行任务.doc

    Java应用程序中的定时任务执行是软件开发中常见的需求,特别是在企业级应用和日历类应用中。标准的Java库提供了`java.util.Timer`和`java.util.TimerTask`类,但它们在处理复杂定时任务时存在局限性,比如无法适应...

    Java 应用程序中定时执行任务的定时器框架

    所有类型的 Java 应用程序一般都需要计划重复执行的任务。企业应用程序需要计划每日的日志或者晚间批处理过程。一个 J2SE或者 J2ME 日历应用程序需要根据用户的约定计划闹铃时间。不过,标准的调度类 Timer 和 ...

    Java应用程序中定时执行任务借鉴.pdf

    在Java应用程序中,定时执行任务是一项常见的需求,无论是企业级应用中的日志清理或批处理,还是个人设备上的日历提醒。然而,Java标准库提供的`java.util.Timer`和`java.util.TimerTask`类虽然简单易用,但在处理...

    Quartz--JAVA定时任务\Java应用:Java调度任务和Spring Quartz (1)

    Java定时任务是应用程序中不可或缺的一部分,它允许程序在特定时间执行特定操作,无需用户干预。在JDK 1.3及以后的版本中,`java.util.Timer`类提供了基础的定时任务支持。不过,`Timer`类的功能相对有限,无法精确...

    JAVA定时运行程序

    本文将详细介绍如何使用`java.util.Timer`类来创建一个能够定时执行特定任务的应用程序。通过分析提供的代码片段,我们将深入探讨其工作原理、关键组件及其在实际开发中的应用。 #### 二、`java.util.Timer`类简介 ...

    java quartz 定时任务

    Java Quartz 是一个强大的开源任务调度库,用于在Java应用程序中创建和管理定时任务。Quartz 提供了丰富的API,使得开发者能够灵活地定义任务,并精确控制任务的执行时间。本项目利用Quartz 实现了基于Cron表达式的...

    java定时关机小程序

    这个程序在日常生活中或企业环境中非常有用,比如在执行大量计算任务后自动关闭电脑,或者在无人值守时进行系统维护。下面我们将深入探讨如何使用Java编写这样的程序,以及涉及的关键技术和知识点。 首先,要实现...

    spring整合java quartz实现动态定时任务的前台网页配置与管理

    在实际项目应用中经常会用到定时任务,可以通过quartz和spring的简单配置即可完成,但如果要改变任务的执行时间、频率,废弃任务等就需要改变配置甚至代码需要重启服务器,这里介绍一下如何通过quartz与spring的组合...

    java定时任务

    Java 定时任务是指在 Java 应用程序中使用 Timer 和 TimerTask 来执行定时任务的机制。通过使用 Java 定时任务,可以在指定的时间点执行特定的任务,从而实现自动化处理和批处理等功能。 在 Java 中,定时任务一般...

    java网上爬虫和定时任务

    Java网上爬虫与定时任务是IT领域中两个重要的技术方向,它们在数据分析、信息收集以及自动化运维等方面有着广泛的应用。本篇文章将详细讲解如何利用Java实现网上爬虫以及结合Quartz实现定时任务。 首先,我们要了解...

    java定时任务开源案例

    Java定时任务是软件开发中一个不可或缺的特性,它允许程序在特定时间执行预定的任务,而无需用户干预。在Java世界里,实现定时任务的方式多种多样,包括但不限于使用Java内置的`java.util.Timer`和`java.util....

    java 定时任务及jar包

    Java定时任务是Java编程中一个重要的特性,它允许开发者安排任务在特定的时间点或周期性地执行。在Java中,我们可以使用内置的`java.util.Timer`类和`java.util.concurrent.ScheduledExecutorService`来实现定时任务...

    java程序自动重新启动

    9. **定时任务**:如果程序需要定期检查重启条件,可以使用Java的ScheduledExecutorService或者第三方库如Quartz来实现定时任务。 通过以上分析,我们可以推测这个程序的工作流程大致如下:Watch.java线程持续监控...

    java定时执行sql语句

    使用jfinal编写的本地应用,压缩文件里包括了eclipse本程序的源代码和可执行的jar文件。 通过配置数据库连接信息和要执行的sql语句,可实现定时执行多个sql语句。 所要执行的语句只能是写死的,可支持sqlserver ...

    java 定时任务写法

    通过Quartz API,开发者可以轻松地在Java应用程序中实现灵活且强大的任务调度功能。无论是简单的重复任务还是复杂的定时任务,Quartz都能够提供强大的支持。此外,Quartz还具有良好的可扩展性和持久化能力,非常适合...

    java定时任务小例子

    在`DoTask`类中,你需要重写`run`方法,放入你需要定时执行的逻辑。例如: ```java import java.util.TimerTask; public class DoTask extends TimerTask { @Override public void run() { System.out.println...

    java 定时执行任务 定时关机 定时重启

    使用Java Swing写的一个小程序,用来定时关机、定时重启、定时执行某一个应用程序。执行时调用cmd命令执行的。其他的,就没什么了,最后用exe4j把jar打包成了exe文件,在本地测能用,不知道其他地方是否能用,内部有...

    JAVA定时执行

    在Java编程中,定时执行任务是一项常见的需求,例如在服务器上定期执行数据备份、日志清理或自动同步等操作。本篇文章将详细讲解如何在Java环境中实现定时执行,并结合提供的文件`ReloadResourceListener.java`, `...

    java scheduler 定时demo

    Java Scheduler 是一个强大的工具,用于在Java应用程序中实现定时任务。它允许开发者安排任务在特定时间执行,或者按一定间隔重复执行。这个“java scheduler 定时demo”应该包含了一个示例项目,演示了如何使用Java...

Global site tag (gtag.js) - Google Analytics