诚之和:在 Java 应用程序中安排重复性任务

本文介绍了如何在Java应用程序中扩展基本的Timer和TimerTask框架,以实现更灵活的重复任务调度。文章通过EggTimer和AlarmClock示例展示了如何安排一次性任务和处理复杂的重复任务,如每天同一时间响起的闹钟。作者提出了一个简单的调度框架,由两个类和一个接口组成,能够处理日历算法,适应夏令时变化。文章还讨论了任务的取消、调度框架的实现、与cron工具的比较以及实时保证问题。
摘要由CSDN通过智能技术生成

java.util.Timer​和​java.util.TimerTask​类(我将二者统称为Java的定时器框架)使得程序员可以轻松地安排简单的任务。(请注意,这些类在 J2ME 中也可用。)在 Java 2 SDK 标准版 1.3 版中引入此框架之前,开发人员必须编写自己的调度程序,这涉及处理线程和​Object.wait()​方法的复杂性。但是,Java 定时器框架不够丰富,无法满足许多应用程序的调度需求。即使是需要每天同时重复的任务也不能直接使用​Timer​进行调度,因为夏令时的来来往往会发生时间跳跃。

本文介绍了一个调度框架,它是对Timer​和​TimerTask​的推广,允许更灵活的调度。该框架非常简单——它由两个类和一个接口组成——而且很容易学习。如果你习惯于使用 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()​方法启动鸡蛋计时器时,它会安排​ aTimerTask​在指定的分钟数后执行。当时间到时, 上的​run()​方法​TimerTask​由​Timer​幕后调用,使其播放声音。然后应用程序在定时器被取消后终止。

安排重复性任务

Timer允许通过指定固定的执行速率或执行之间的固定延迟来安排任务重复执行。但是,有许多应用程序具有更复杂的调度要求。例如,每天早上在同一时间响起叫醒电话的闹钟不能简单地使用 86400000 毫秒(24 小时)的固定速率时间表,因为在时钟前进的日子里,闹钟会太晚或太早或向后(如果您的时区使用夏令时)。解决方案是使用日历算法来计算每日事件的下一次预定发生。这正是调度框架所支持的。考虑AlarmClock 清单 2 中的实现(请参阅相关链接以下载调度框架的源代码,以及包含框架和示例的 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();
            }
            pri
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_45378258

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值