用java.util.Timer定时执行任务

用java.util.Timer定时执行任务

1. 新建一个task 实现run方法

2. Timer t = new Time() 

3.   T.schedule(task );等等4个方法去执行

如果要在程序中定时执行任务,可以使用java.util.Timer这个类实现。使用Timer类需要一个继承了java.util.TimerTask的类。TimerTask是一个虚类,需要实现它的run方法,实际上是他implements了Runnable接口,而把run方法留给子类实现。
      下面是我的一个例子:

class Worker extends TimerTask {
  public void run() {
    System.out.println("我在工作啦!");
  }
}


      Timer类用schedule方法或者scheduleAtFixedRate方法启动定时执行,schedule重载了四个版本,scheduleAtFixedRate重载了两个。每个方法的实现都不同,下面是每个方法的说明:

schedule

public void schedule(TimerTask task,

                     long delay)

Schedules the specified task for execution after the specified delay. 

Parameters: 

task - task to be scheduled. 

delay - delay in milliseconds before task is to be executed. 

Throws: 

IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative. 

IllegalStateException - if task was already scheduled or cancelled, or timer was cancelled.

说明:该方法会在设定的延时后执行一次任务。

schedule

public void schedule(TimerTask task,

                     Date time)

Schedules the specified task for execution at the specified time. If the time is in the past, the task is scheduled for immediate execution. 

Parameters: 

task - task to be scheduled. 

time - time at which task is to be executed. 

Throws: 

IllegalArgumentException - if time.getTime() is negative. 

IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.

说明:该方法会在指定的时间点执行一次任务。

schedule

public void schedule(TimerTask task,

                     long delay,

                     long period)

Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period. 

In fixed-delay execution, each execution is scheduled relative to the actual execution time of the previous execution. If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well. In the long run, the frequency of execution will generally be slightly lower than the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate). 

Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other words, it is appropriate for activities where it is more important to keep the frequency accurate in the short run than in the long run. This includes most animation tasks, such as blinking a cursor at regular intervals. It also includes tasks wherein regular activity is performed in response to human input, such as automatically repeating a character as long as a key is held down. 

Parameters: 

task - task to be scheduled. 

delay - delay in milliseconds before task is to be executed. 

period - time in milliseconds between successive task executions. 

Throws: 

IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative. 

IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.

说明:该方法会在指定的延时后执行任务,并且在设定的周期定时执行任务。

schedule

public void schedule(TimerTask task,

                     Date firstTime,

                     long period)

Schedules the specified task for repeated fixed-delay execution, beginning at the specified time. Subsequent executions take place at approximately regular intervals, separated by the specified period. 

In fixed-delay execution, each execution is scheduled relative to the actual execution time of the previous execution. If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well. In the long run, the frequency of execution will generally be slightly lower than the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate). 

Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other words, it is appropriate for activities where it is more important to keep the frequency accurate in the short run than in the long run. This includes most animation tasks, such as blinking a cursor at regular intervals. It also includes tasks wherein regular activity is performed in response to human input, such as automatically repeating a character as long as a key is held down. 

Parameters: 

task - task to be scheduled. 

firstTime - First time at which task is to be executed. 

period - time in milliseconds between successive task executions. 

Throws: 

IllegalArgumentException - if time.getTime() is negative. 

IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.

说明:该方法会在指定的时间点执行任务,然后从该时间点开始,在设定的周期定时执行任务。特别的,如果设定的时间点在当前时间之前,任务会被马上执行,然后开始按照设定的周期定时执行任务。

在应用开发中,经常需要一些周期性的操作,比如每5分钟检查一下新邮件等。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。比如下面的代码每5分钟检查一遍是否有新邮件:
        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本身会每隔5分钟调用一遍server.checkNewMail()方法,不需要自己启动线程。Timer本身也是多线程同步的,多个线程可以共用一个Timer,不需要外部的同步代码。
    在《The Java Tutorial》中有更完整的例子:
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(); //Not necessary because we call System.exit
            System.exit(0);   //Stops the AWT thread (and everything else)
        }
        }
    }
    ...
}
这段程序,每隔3秒响铃一声,并打印出一行消息。循环3次。程序输出如下:
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

Timer类也可以方便地用来作为延迟执行,比如下面的代码延迟指定的时间(以秒为单位)执行某操作。类似电视的延迟关机功能。
...
public class ReminderBeep {
    ...
    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)
        }
    }
    ...
}


1. 有朋友来信问,希望自己的Task一直运行,而不是像上面的RemindTask那样仅循环3次。
这 很简单,可能这位朋友把Task的作用理解有误,Task仅代表了一次的动作。而不是让Task完成循环。上面的RemindTask中之所以有一个计 数,是因为要运行3次停止,如果需要一直保持运行。把上面有关的计数的代码全部去除即可。其实Timer中并没有提供运行指定次数后即停止的机制,所以, 上面的计数满足了这个功能需要。

2. 能否设置Timer的优先级?
Timer中是利用一个线程来进行计时及周期触发动作的。现 在的Timer实现中并没有提供设置优先级的方法,在你调用new Timer()时线程已经启动,所以,除非Timer的以后版本中在构造方法中增加优 先级参数,否则,我们是不能控制其优先级的。现在的Timer默认是在Thread.NORM_PRIORITY优先级下运行的。但是Timer提供了一 个Timer(boolean isDaemon)的构造方法,可以将Timer设置为daemon线程。这样,在你的程序中其它线程都运行完毕后,程序 就可以退出了。

3. Timer是不是实现了精确地定时?
否。Timer中也是采用Object.wait(long time)来实现定时的,由于Object.wait()不保证精确计时,所以Timer也不是一个精确的时钟。如果是实时系统,不能依赖Timer

4. liangyiqing) 假如我在一个Timer类里面再定义一个Timer类,如果外层定义的时间是24小时循环一次,而内层定义的是1小时循环一次,意思就是当一个小时内层运 行完一次之后,内层Timer释放资源,我想问,外层的Timer是不是也会释放,还是24小时之中一直都在占用?
我不太清楚你的占用资源是什么 意思,如果你在Task中用到一些资源,这些资源应该在Task运行结束后即刻释放,尤其对竞态条件,更应该占用尽量少的时间。一般来说,一次Task的 运行时间,将少于你设定的周期。否则,Task将在Timer中堆积起来。如果你要实现上面说的每24小时和每1小时两个周期的操作,可以使用一个 Timerschedule两个Task即可。

5. Timer是否可以在多线程环境下使用?
可以。Timer中用于存储Task的容器是同步了的,保证了多线程环境先的安全使用。

6. austin1979 )请问,定时的时间能为变量,可以在程序中变化吗?就是说定时的时间可以又界面来控制。
一 个Timer可以控制任意多个Task的不同周期设定的触发。也就是说,这个Timer类似于可以定多个时间的闹钟,比如我的手机就有3个闹 钟 :)  。但是一旦一个Task 已经进行了schedule了,那么就不能再次进行设定。所以,也不可能再改变其周期、延迟等等设定了。可以看下面 的代码:
            synchronized(task.lock) {
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                task.nextExecutionTime = time;
                task.period = period;
                task.state = TimerTask.SCHEDULED;
            }

7. eqingtian)可不可以认为Timer就是一个线程的发射器?
Timer中仅有一个存储TaskQueue和一个调度所有Task的线程。不管你schedule几次,在Timer上加了几个Task,都只有一个后台的线程进行调度。 

2004813日 9:53


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值