Java定时任务Timer

  项目中要定期执行一个程序,在实现过程中尝试使用timer来完成这项工作,之前没有用过timer正好通过项目来熟悉并完成工作。

 TimerTask是个抽象类,他扩展了Object并实现了Runnable接口,因此你必须在自己的Task中实现public void run()方法。这也就是我们需要执行的具体任务。Timer实际上是用来控制Task的,他提供的主要方法是重载的schedule()方法。我们这里将使用schedule(TimerTask task,long time,long internal)方法来说明如何使用它。

/**
 * TimerUser.java
 * com.ibm.eu.services.base.pa
 *
 * Function: TODO 
 *
 *   ver     date      		author
 * ──────────────────────────────────
 *   		 May 24, 2013 		hanzy
 *
*/

package com.ibm.eu.services.base.pa;
 
import java.util.*;
import java.io.*;

public class TimerUser
{
 public static void main(String[] args)
 {
  TimeTask timeTask  = new TimeTask();
  timeTask.start(1,5); 
 } 
}

class TimeTask
{
 private Timer timer;

 public TimeTask()
 {
  timer = new Timer();
 }
 
 private TimerTask task = new TimerTask()
 {
  public void run()
  {
   
    System.out.println("test for timer");
   
  } 
 };
 
 public void start(int delay,int internal )
 {
  timer.schedule(task,delay*1000,internal*1000); 
 }
 
}


通过上述代码可以解决定时执行的问题,通过继续查询资料发现有的博客说timer从在一些缺陷:

Timer计时器有管理任务延迟执行("如1000ms后执行任务")以及周期性执行("如每500ms执行一次该任务")。但是,Timer存在一些缺陷,因此你应该考虑使用ScheduledThreadPoolExecutor作为代替品,Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;ScheduledThreadExecutor只支持相对时间。

Timer的另一个问题在于,如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以TimerTask抛出的未检查的异常会终止timer线程。这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被安排但尚未执行的TimerTask永远不会再执行了,新的任务也不能被调度了。

但是ScheduledThreadPoolExecutor也有不利的地方,就是只能按相对的时间的,而不能设置具体某个时刻之后执行,如每天晚上12点定时执行任务之类的要求使用Timer更合适,如果是周期性的重复工作可以考虑使用ScheduledThreadPoolExecutor。

 

再看看API的具体信息

public class ScheduledThreadPoolExecutor
extends ThreadPoolExecutor
implements ScheduledExecutorService
ThreadPoolExecutor,它可另行安排在给定的延迟后运行命令,或者定期执行命令。需要多个辅助线程时,或者要求 ThreadPoolExecutor 具有额外的灵活性或功能时,此类要优于 Timer。

一旦启用已延迟的任务就执行它,但是有关何时启用,启用后何时执行则没有任何实时保证。按照提交的先进先出 (FIFO) 顺序来启用那些被安排在同一执行时间的任务。

虽然此类继承自 ThreadPoolExecutor,但是几个继承的调整方法对此类并无作用。特别是,因为它作为一个使用 corePoolSize 线程和一个无界队列的固定大小的池,所以调整 maximumPoolSize 没有什么效果。

扩展注意事项:此类重写 AbstractExecutorService 的 submit 方法,以生成内部对象控制每个任务的延迟和调度。若要保留功能性,子类中任何进一步重写的这些方法都必须调用超类版本,超类版本有效地禁用附加任务的定制。但是,此类提供替代受保护的扩展方法 decorateTask(为 Runnable 和 Callable 各提供一种版本),可定制用于通过 execute、submit、schedule、scheduleAtFixedRate 和 scheduleWithFixedDelay 进入的执行命令的具体任务类型。默认情况下,ScheduledThreadPoolExecutor 使用一个扩展 FutureTask 的任务类型。但是,可以使用下列形式的子类修改或替换该类型。

 

虽然timer存在一些问题,不过因为定期执行任务的程序比较简单,服务器的也比较稳定,采用timer还是可以的。

在windows中也可以建立定期的执行任务就是通过Task Scheduler来建立,如果有需要的话可以自己去了解一下,比较不错的一个工具

 

你可能感兴趣的:(Java定时任务Timer)