在Java中创建一个重复的定时器提醒

12

我希望有一个类能够每2秒钟更改自己的私有变量。我知道如果我这样做:

import java.util.Timer;
//...
Timer timer;
//...
timer.schedule(new ChangeSomething(), 2000);

它将在2秒后执行ChangeSomething()函数,是否有一种方法可以让它每2秒钟执行一次某个操作,或者如果我将其放在ChangeSomething()函数内部呢?

    timer.schedule(new ChangeSomething(), 2000);

这会有效吗?

另外,timer.cancel() 究竟是什么意思?

4个回答

14
使用timer.scheduleAtFixedRate()方法使任务每两秒重复执行:

使用timer.scheduleAtFixedRate()方法,从指定时间开始安排指定任务以固定速率执行。随后的执行大约在固定的时间间隔内进行,由指定的时间间隔分隔。

Timer.cancel()的javadoc中得知:

终止此计时器,放弃任何当前已经安排的任务。不会干涉当前正在执行的任务(如果存在)。一旦计时器被终止,它的执行线程将平稳地终止,并且不能再在其上安排更多任务。

编辑:

与仅执行单个任务一次的Timer的内部执行线程相关:

在最后一个对Timer对象的引用消失并且所有未完成的任务已经执行之后,计时器的任务执行线程将平稳地终止(并成为垃圾回收的一部分)。但是,这可能需要任意长的时间来发生。默认情况下,任务执行线程不作为守护线程运行,因此它有可能阻止应用程序终止。如果调用者想要快速终止定时器的任务执行线程,则应调用定时器的取消方法。


关于timer.cancel(),我不明白的是,在我创建一个仅被调度一次的任务后,是否需要执行它以确保它不会再次执行? - SIMEL
Timer 的 Javadoc 表示这不是必需的,计时器的执行线程将终止。但是,它确切地指出这可能需要任意长的时间,并且 cancel() 可以用于更快地终止它。(将相关段落从 Javadoc 复制到答案中)。 - hmjd

7
您需要调用Timer的另一种调度方法,称为scheduleAtFixedRate(...),它可以获取3个参数。前两个参数与您使用的"schedule"方法相同,而第三个参数表示连续任务执行之间的时间间隔,以毫秒为单位。
import java.util.Timer;
//...
Timer timer;
//...
timer.scheduleAtFixedRate(new ChangeSomething(), 2000, 2000);

您可以在此处查看此方法的Java API文档:http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask,java.util.Date,long)。

6

这里有一个例子

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Test extends TimerTask {
   private int age;

   public Test() {
       Timer timer = new Timer();
       timer.scheduleAtFixedRate(this, new Date(), 2000);
   }

   /**
    * Implements TimerTask's abstract run method.
    */
    public void run(){
      //toy implementation
      System.out.print("Changing Data ... before change age is "+age+" ");
      changeAge();
      System.out.println("after change age is "+age);

    }


   private void changeAge() {
      age = (int)Math.round(Math.random()*1000);
   }

  public static void main(String[] args) {
          new Test();
  }

}


新的计时器(); = 不可能的,你需要添加参数对吧? - Sven van den Boogaart
根据Java文档:http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html,Timer确实具有默认构造函数。 - Matthew S.

0
更准确地说:ChangeSomething() 是 ChangeSomething 类的构造函数。当你将 ChangeSomething 实例对象传递给计时器时,构造函数将立即执行,而不是在 2 秒后执行。该对象的 run() 方法将在 2 秒后触发。
要每隔 2 秒执行一次该 run() 方法,请使用 schedule(TimerTask task, long delay, long period)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接