使用java.util.Timer

    |     2015年4月29日   |   Java面向对象高级特性   |     0 条评论   |    1587

应用里常有周期性工作,比如每 5 分钟检查一次新邮件。这类任务用 java.util.Timer 最省事:它自己维护调度线程,不必手写循环休眠。

Timer 也适合延迟执行(类似电视的延时关机)。多个线程可以共用一个 Timer,它内部是同步的,一般不必再包一层锁。

一、周期调度

下面这段每 5 分钟检查一遍新邮件。new Timer(true) 表示守护线程,主程序退出时定时任务一并结束:

private java.util.Timer timer;
timer = new Timer(true);
timer.schedule(new java.util.TimerTask() {
    public void run() {
        // server.checkNewMail(); 检查新邮件
    }
}, 0, 5 * 60 * 1000);

写完这几行,Timer 就会按周期调用 run(),不用自己 start 线程。

二、《The Java Tutorial》里的蜂鸣例子

下面程序每隔 1 秒响一次,共 3 次,然后退出(原文把间隔口误写成“3 秒”,与代码 1*1000 及注释 one second 不符,这里按代码纠正):

public class AnnoyingBeep {
    Toolkit toolkit;
    Timer timer;

    public AnnoyingBeep() {
        toolkit = Toolkit.getDefaultToolkit();
        timer = new Timer();
        timer.schedule(new RemindTask(),
            0,        // initial delay
            1 * 1000);  // subsequent rate
    }

    class RemindTask extends TimerTask {
        int numWarningBeeps = 3;

        public void run() {
            if (numWarningBeeps > 0) {
                toolkit.beep();
                System.out.println("Beep!");
                numWarningBeeps--;
            } else {
                toolkit.beep();
                System.out.println("Time's up!");
                // timer.cancel(); // 不必:下面 System.exit 会停掉 AWT 及其它线程
                System.exit(0);
            }
        }
    }
    ...
}

输出类似:

Task scheduled.
Beep!
Beep!      // one second after the first beep
Beep!      // one second after the second beep
Time's up! // one second after the third beep

三、延迟执行

指定秒数之后再做一件事,构造时把延迟传给 schedule 的一次性重载即可:

public class ReminderBeep {
    Toolkit toolkit;
    Timer timer;
    ...
    public ReminderBeep(int seconds) {
        toolkit = Toolkit.getDefaultToolkit();
        timer = new Timer();
        timer.schedule(new RemindTask(), seconds * 1000);
    }
    class RemindTask extends TimerTask {
        public void run() {
            System.out.println("Time's up!");
            toolkit.beep();
            // timer.cancel(); // Not necessary because we call System.exit
            System.exit(0); // Stops the AWT thread (and everything else)
        }
    }
    ...
}
用法 API 含义
周期任务 schedule(task, delay, period) 先等 delay,再每隔 period 执行
延迟一次 schedule(task, delay) delay 毫秒后执行一次
守护 Timer new Timer(true) 进程退出时不挡住 JVM

一句话总结:周期或延时任务交给 Timer + TimerTask,schedule 的 delay/period 用毫秒,别自己起线程空转。

转载请注明来源:使用java.util.Timer
本文链接地址:https://ai.zhousir.top/?p=593
回复 取消