scheduleAtFixedRate 的使用与实践

发布时间:2023-05-19

一、基本概述

scheduleAtFixedRate 是 Java 中的一个定时器,用于周期性地执行任务,其使用方式类似于 Timer 类中的 schedule 方法。 scheduleAtFixedRate 有三个参数:

public void scheduleAtFixedRate(TimerTask task, long delay, long period)

其中,第一个参数 task 表示需要周期执行的任务,是一个 TimerTask 类型的对象;第二个参数 delay 表示任务的延迟执行时间,单位为毫秒;第三个参数 period 表示任务的周期执行时间,单位为毫秒。

二、使用案例

假设我们需要每隔 2 秒输出一个时间戳,可以使用 scheduleAtFixedRate 实现:

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo {
    public static void main(String[] args) {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println(new Date());
            }
        };
        timer.scheduleAtFixedRate(task, 0, 2000);
    }
}

三、注意事项

在使用 scheduleAtFixedRate 时,需要注意以下几点:

  1. 如果任务执行时间超过了周期时间 period,则任务会按照实际执行时间来计算下一次执行时间,即有可能出现“任务重叠”的情况。
  2. 如果任务执行时间小于周期时间 period,则任务会按照 period 来计算下一次执行时间。
  3. 如果任务执行时间过长,导致周期性任务无法按时执行,则需要考虑使用 Timer 的另一种任务调度方式 schedule 方法。

四、错误示范

下面是一种错误的使用 scheduleAtFixedRate 的示范:

import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo2 {
    public static void main(String[] args) {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis());
                try {
                    Thread.sleep(5000); // 线程休眠 5 秒钟
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        timer.scheduleAtFixedRate(task, 0, 2000);
    }
}

这个示范会输出一串连续的时间戳,并且时间戳之间的时间间隔可能会大于 2 秒。这是因为任务主体中休眠了 5 秒钟,造成了任务重叠的情况。正确的方式应该是使用 schedule 方法:

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo2 {
    public static void main(String[] args) {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println(new Date());
            }
        };
        timer.schedule(task, 0, 2000);
    }
}

这个示范会每隔 2 秒输出一个时间戳,并且不会出现任务重叠的情况。

五、总结

scheduleAtFixedRate 是 Java 中的一个定时器,用于周期性地执行任务。在使用这个定时器时,需要注意任务执行时间是否超过周期时间以及是否会出现任务重叠的情况。如果任务执行时间过长,可以考虑使用 Timer 的另一种任务调度方式 schedule 方法。