所有类型的 Java 应用程序一般都需要计划重复执行的任务。企业应用程序需要计划每日的日志或者晚间批处理过程。一个 J2SE 或者 J2ME 日历应用程序需要根据用户的约定计划闹铃时间。不过,标准的调度类 Timer
和 TimerTask
没有足够的灵活性,无法支持通常需要的计划任务类型。在本文中,Java 开发人员 Tom White 向您展示了如何构建一个简单通用的计划框架,以用于执行任意复杂的计划任务。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
我将把 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 类
package org.tiling.scheduling.examples;
import java.util.Timer;
import java.util.TimerTask;
public class EggTimer {
private final Timer timer = new Timer();
private final int minutes;
public EggTimer(int minutes) {
this.minutes = minutes;
}
public void start() {
timer.schedule(new TimerTask() {
public void run() {
playSound();
timer.cancel();
}
private void playSound() {
System.out.println("Your egg is ready!");
// Start a new thread to play a sound...
}
}, minutes * 60 * 1000);
}
public static void main(String[] args) {
EggTimer eggTimer = new EggTimer(2);
eggTimer.start();
}
}
EggTimer 实例拥有一个 Timer
实例,用于提供必要的计划。用 start()
方法启动煮蛋计时器后,它就计划了一个 TimerTask
,在指定的分钟数之后执行。时间到了,Timer
就在后台调用 TimerTask
的 start()
方法,这会使它发出声音。在取消计时器后这个应用程序就会中止。
计划重复执行的任务
通过指定一个固定的执行频率或者固定的执行时间间隔,Timer
可以对重复执行的任务进行计划。不过,有许多应用程序要求更复杂的计划。例如,每天清晨在同一时间发出叫醒铃声的闹钟不能简单地使用固定的计划频率 86400000 毫秒(24 小时),因为在钟拨快或者拨慢(如果您的时区使用夏令时)的那些天里,叫醒可能过晚或者过早。解决方案是使用日历算法计算每日事件下一次计划发生的时间。而这正是计划框架所支持的。考虑清单 2 中的 AlarmClock
实现(有关计划框架的源代码以及包含这个框架和例子的 JAR 文件,请参阅 参考资料):
清单 2. AlarmClock 类
package org.tiling.scheduling.examples;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.tiling.scheduling.Scheduler;
import org.tiling.scheduling.SchedulerTask;
import org.tiling.scheduling.examples.iterators.DailyIterator;
public class AlarmClock {
private final Scheduler scheduler = new Scheduler();
private final SimpleDateFormat dateFormat =
new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS");
private final int hourOfDay, minute, second;
public AlarmClock(int hourOfDay, int minute, int second) {
this.hourOfDay = hourOfDay;
this.minute = minute;
this.second = second;
}
public void start() {
scheduler.schedule(new SchedulerTask() {
public void run() {
soundAlarm();
}
private void soundAlarm() {
System.out.println("Wake up! " +
"It's " + dateFormat.format(new Date()));
// Start a new thread to sound an alarm...
}
}, new DailyIterator(hourOfDay, minute, second));
}
public static void main(String[] args) {
AlarmClock alarmClock = new AlarmClock(7, 0, 0);
alarmClock.start();
}
}
注意这段代码与煮蛋计时器应用程序非常相似。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
...
分享到:
相关推荐
所有类型的 Java 应用程序一般都需要计划重复执行的任务。企业应用程序需要计划每日的日志或者晚间批处理过程。一个 J2SE或者 J2ME 日历应用程序需要根据用户的约定计划闹铃时间。不过,标准的调度类 Timer 和 ...
在Java应用程序中,定时执行任务是一项常见的需求,无论是企业级应用中的日志清理或批处理,还是个人设备上的日历提醒。然而,Java标准库提供的`java.util.Timer`和`java.util.TimerTask`类虽然简单易用,但在处理...
所有类型的 Java 应用程序一般都需要计划重复执行的任务。企业应用程序需要计划每日的日志或者晚间批处理过程。一个 J2SE 或者 J2ME 日历应用程序需要根据用户的约定计划闹铃时间。不过,标准的调度类 Timer 和 ...
Java定时任务是应用程序中不可或缺的一部分,它允许程序在特定时间执行特定操作,无需用户干预。在JDK 1.3及以后的版本中,`java.util.Timer`类提供了基础的定时任务支持。不过,`Timer`类的功能相对有限,无法精确...
在Android开发中,有时我们需要实现延时或重复执行的任务,比如定时更新UI、定期发送心跳包、延时启动服务等。这些需求可以通过多种方式来实现,包括`Timer`、`Handler`、`Thread`以及`AlarmManager`。下面将详细...
3. **函数与方法**:函数是组织代码的单元,可以重复使用并执行特定任务。Java的方法定义了操作数据的方式,包括参数传递和返回值。 4. **类与对象**:Java是面向对象的,所以理解和创建类及对象是基础。类是对象的...
此“JAVA应用程序设计源码.rar”压缩包很可能包含了一系列的Java源代码文件,用于教学或实践目的,让我们一起探讨其中可能涉及的一些Java编程知识点。 1. **类与对象**:在Java中,一切皆为对象。源码中可能会包含...
4. **Web容器**:如Apache Tomcat,是运行Java Web应用程序的软件,它管理Servlet和JSP的生命周期,处理HTTP请求,并将响应返回给客户端。 5. **前端技术**:尽管标签中未明确提及,但Java Web应用通常会涉及到HTML...
Quartz是一款强大的开源任务调度库,它能够与Java应用程序无缝集成,实现复杂的时间触发任务。当我们遇到Spring定时器执行两次或者更多次的问题时,这通常是由于配置不当或者多线程并发导致的。下面将详细介绍如何...
Java Quartz 是一个强大的开源任务调度库,用于在Java应用程序中安排和执行重复或定时的任务。它允许开发者定义作业(Jobs)和触发器(Triggers),并以灵活的时间表来安排这些任务。Quartz 可以独立于应用服务器...
在Java软件开发中,自动执行任务是一项常用的技术,特别是在Web应用程序中。Java提供了多种方式来实现定时任务,如Java的定时器(java.util.Timer)和Quartz库。这里我们将重点关注如何利用Servlet监听器...
通过解决书中关于这些话题的例题,学习者能学会如何根据不同的条件执行不同的代码块,以及如何重复执行某段代码直到满足特定条件。这对于实现复杂的逻辑和算法至关重要。 函数的使用和定义也是JAVA编程的重要概念。...
这个程序在日常生活中或企业环境中非常有用,比如在执行大量计算任务后自动关闭电脑,或者在无人值守时进行系统维护。下面我们将深入探讨如何使用Java编写这样的程序,以及涉及的关键技术和知识点。 首先,要实现...
Java多线程编程是开发高并发应用的关键技术之一,它涉及到如何有效地利用系统资源,提高程序的执行效率。在这个场景中,我们关注的是一个特定的多线程问题:A线程需要等待B线程和C线程执行完毕后再开始执行,同时...
本文将详细介绍如何使用`java.util.Timer`类来创建一个能够定时执行特定任务的应用程序。通过分析提供的代码片段,我们将深入探讨其工作原理、关键组件及其在实际开发中的应用。 #### 二、`java.util.Timer`类简介 ...
JAVA语言可以用于开发各种应用程序,包括桌面应用、移动应用、Web应用等。Android移动开发平台使用Java语言作为官方推荐开发语言。 4. JAVA语法 JAVA语法包括变量声明、数据类型、运算符、控制流语句、循环语句等...
通过学习,开发者可以掌握如何创建可扩展、可维护的Java应用程序,理解模块化设计的最佳实践,以及OSGi在实际项目中的具体应用。 总之,Java应用架构设计中的模块化模式与OSGi技术是提高软件质量、简化复杂性的关键...
在Java中,我们使用if...else语句进行条件判断,通过while和for循环实现重复执行的任务。掌握这些基本逻辑结构是编写任何程序的基础。 三、面向对象编程 Java的核心是面向对象编程(OOP)。OOP基于类和对象的概念,...
描述中的重复内容暗示这是一个关于Java ATM程序的压缩文件,可能是包含了源代码、编译后的可执行文件或者相关的文档资料。".rar"是常见的压缩文件格式,用户需要解压才能访问内部内容。通常,这类程序的源代码会分为...
这是Java提供的两种图形用户界面(GUI)开发工具包,用于创建桌面应用程序。 13. **Java EE和Spring框架** 对于Web开发,Java Enterprise Edition(Java EE)提供了一系列服务器端技术,而Spring框架则简化了企业...