timer定时任务

如果要执行一些简单的定时器任务,无须做复杂的控制,也无须保存状态,那么可以考虑使用JDK 入门级的定期器Timer来执行重复任务。
 
一、原理
 
JDK中,定时器任务的执行需要两个基本的类:
    java.util.Timer;
    java.util.TimerTask;
 
要运行一个定时任务,最基本的步骤如下:
1、建立一个要执行的任务TimerTask
2、创建一个Timer实例,通过Timer提供的schedule()方法,将 TimerTask加入到定时器Timer中,同时设置执行的规则即可。
 
当程序执行了Timer初始化代码后,Timer定时任务就会按照设置去执行。
 
Timer中的schedule()方法是有多种重载格式的,以适应不同的情况。该方法的格式如下:
 void schedule(TimerTask task, Date time)
          安排在指定的时间执行指定的任务。
 void schedule(TimerTask task, Date firstTime, long period)
          安排指定的任务在指定的时间开始进行重复的固定延迟执行。
 void schedule(TimerTask task, long delay)
          安排在指定延迟后执行指定的任务。
 void schedule(TimerTask task, long delay, long period)
          安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
 
Timer是线程安全的,此类可扩展到大量同时安排的任务(存在数千个都没有问题)。其所有构造方法都启动计时器线程。可以调用cancel() 终止此计时器,丢弃所有当前已安排的任务。purge()从此计时器的任务队列中移除所有已取消的任务。此类不提供实时保证:它使用 Object.wait(long) 方法来安排任务。
 
TimerTask是一个抽象类,由 Timer 安排为一次执行或重复执行的任务。它有一个抽象方法run()----计时器任务要执行的操作。因此,每个具体的任务类都必须继承TimerTask类,并且重写run()方法。另外它还有两个非抽象的方法:
 boolean cancel()
          取消此计时器任务。
 long scheduledExecutionTime()
          返回此任务最近实际执行的安排执行时间。
 
二、例子
 
下面用Timer实现一个简单例子:
 
package stu.timer;
 
import java.util.Date;
import java.util.TimerTask;
 
/**
* 重复执行的任务
*
* @author leizhimin2008-10-9 9:20:20
*/
public class TestTimerTask extends TimerTask {
        /**
         * 此计时器任务要执行的操作。
         */
        public void run() {
                Date executeTime = new Date(this.scheduledExecutionTime());
                System.out.println("本次任务执行的时间是" + executeTime);
        }
}
 
package stu.timer;
 
import java.util.Timer;
import java.util.TimerTask;
 
/**
* 测试JDK Timer的执行
*
* @author leizhimin2008-10-9 9:24:35
*/
public class TestTimer {
        public static void main(String[] args) {
                Timer timer = new Timer();
                TimerTask task = new TestTimerTask();
                timer.schedule(task, 500L, 1000L);
        }
}
 
运行结果:
本次任务执行的时间是Thu Oct 09 09:47:57 CST 2008
本次任务执行的时间是Thu Oct 09 09:47:58 CST 2008
本次任务执行的时间是Thu Oct 09 09:47:59 CST 2008
本次任务执行的时间是Thu Oct 09 09:48:00 CST 2008
本次任务执行的时间是Thu Oct 09 09:48:01 CST 2008
本次任务执行的时间是Thu Oct 09 09:48:02 CST 2008
本次任务执行的时间是Thu Oct 09 09:48:03 CST 2008
本次任务执行的时间是Thu Oct 09 09:48:04 CST 2008
本次任务执行的时间是Thu Oct 09 09:48:05 CST 2008

扩展:

继承TimerTask,重写run方法

 

package bamboo.task;

 

import java.util.TimerTask;

 

public class TimeTaskTest extends TimerTask{

 

 @Override

 publicvoid run() {

 System.out.println("hi");

 }

 

}

 

通过timer来设置某个时间来调用,或者是相隔多长时间调用

 

package bamboo.test;

 

import java.util.Date;

import java.util.Timer;

 

import bamboo.task.TimeTaskTest;

 

public class TimeTest {

 staticTimeTaskTest test=new TimeTaskTest();

 

 publicstatic void main(String [] args){

  Timertimer=new Timer();

 

  //启动和间隔的时间1000毫秒

 

 //timer.schedule(test,0,1000);

 

  //设置什么时候执行

 //timer.schedule(test, new Date());

 }

}

 

 

 

 

//

另一种方法

 

用线程很容易实现的。而且比较灵活。下面是一个示例你看看吧:

public class Test implementsRunnable {

 int start = 0;

 int end = 0;

 

 public Test(int end) {

 new Thread(this).start();

 this.end = end;

 }

 

 public void run() {

 while(true) {

  try {

   Thread.sleep(1000);

  } catch (InterruptedException e) {

   e.printStackTrace();

  }

  if(start == end)

   print();

  start++;

 }

 }

 private void print() {

 System.out.println("你的任务在"+end+"秒钟后执行了");

 }

 public static void main(String[] args) {

 new Test(3);

 }

}

另外Java里也有定时器类Timer也可以的,但它的本质也是线程。

///

写一个批处理就可以了。所谓的批处理就是.bat文件。然后把这个文件添加到系统中的“任务计划”中,定时执行这个bat文件就可以了。至于bat文件里面的内容,那就看你调用什么程序了。下面是一个bat文件调用重启命令的例子:

 

echo %date%-%time%时开始重启 >D:\重启日志.TXT

shutdown -r -f

echo 在%date%-%time%时重启完毕 >D:\重启日志.TXT

 

并且这个执行完毕之后,在d盘重启日志文档中写入重启时间和重启完毕的时间。

//

使用此封装可以轻松定时发送邮件、发短信、定制闹钟等。

一共2个类:

com.ab.oa.timer.OpenTask.java(开启定时任务)

com.ab.oa.timer.TimerTaskProxy.java(定时任务的代理类)

com.ab.oa.timer.MyTask.java(测试Demo

package com.ab.oa.timer;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import com.sinosoft.util.logging.LogFactory;
import com.sinosoft.util.logging.Logger;

/**
 *
开启定时任务:可以指定执行多少次,是否一直执行,执行的频率
 *
构造方法参数依次为:String beginTime,boolean exeForEver, int exeNum, long period
 *
 * @author uwaysoft
魏韶颖
 * @version 1.0
 * @time 2009年
4月20日14:07:18
 */
public final class OpenTask {

 private static Logger logger = LogFactory.getLogger(OpenTask.class);
  
 private static final Timer timer = new Timer();
 
 private String beginTime;
 
 private boolean exeForEver;
 
 private int exeNum;
 
 private long period;

 /**
  *
  * @param beginTime
任务第一次开始执行时间格式如:2009-09-01 08:30:00
  * @param exeForEver
此定时任务是否一直执行,如果为true参数exeNum将忽略
  * @param exeNum
任务总共执行多少次数如果=1参数period可随意
  * @param period
每隔多长时间执行一次单位毫秒如:24*60*60*1000就是一天
  */
 public OpenTask(String beginTime, boolean exeForEver, int exeNum, longperiod) {
  super();
  this.beginTime = beginTime;
  this.exeForEver = exeForEver;
  this.exeNum = exeNum;
  this.period = period;
 }
 
 
 /**
  *
开启定时任务
  * @param subClassName
继承了TimerTask的子类名
  *
  */
 public void openTimerTask(String subClassName) {
  try {
   Date date = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss").parse(this.beginTime);
   if(exeForEver) {
    if(period < 1) {
     logger.info("
错误的执行周期!周期 = " + period + "毫秒");
     return;
    }else {

    if (date.before(new Date())) {
       date = this.addDay(date);
      }
     TimerTask timerTask = (TimerTask)Class.forName(subClassName).newInstance();
     //System.out.println("--period = " +period + "
毫秒");
     timer.scheduleAtFixedRate(timerTask, date,period);
     //
区别在于如果超时会补上任务
     //timer.schedule(timerTask, date, period);
     logger.info("
定时任务监控线程已成功启动...执行类型:一直执行!");
    }
   }else {
    if(exeNum < 1) {
     logger.info("
执行次数<1,定时任务不会执行!");
     return;
    }else {
//     TimerTask timerTask = (TimerTask)Class.forName(subClassName).newInstance();
//     if(exeNum == 1) {
//      timer.scheduleAtFixedRate(newTimerTaskProxy(subClassName,exeNum,timer), date, period); 
//      logger.info("
定时任务已经成功启动...执行次数1");
//     }else {
//      timer.scheduleAtFixedRate(newTimerTaskProxy(subClassName,exeNum,timer), date, period);
//      logger.info("
定时任务已经成功启动...执行次数" + exeNum + "");
//     }
     timer.schedule(newTimerTaskProxy(subClassName,exeNum,timer), date,period);  
     logger.info("
定时任务监控线程已经成功启动...预计执行次数" +exeNum + "");
    }
   }
  } catch (ParseException e) {
   e.printStackTrace();
   logger.info("
传入的时间格式不正确,定时任务不会执行!");
   return;
  } catch (InstantiationException e) {
   logger.info("
不能实例化指定类:" + subClassName);
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   logger.info("
不能实例化指定类:" + subClassName);
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   logger.info("
不能实例化指定类:

" + subClassName);
   e.printStackTrace();
  }
 }
 

// 增加或减少天数

    public Date addDay(Date date) {
     Date sysDate = new Date();
     long t = (sysDate.getTime() - date.getTime())/(3600 * 24 * 1000);
     Calendar startDT = Calendar.getInstance();
  startDT.setTime(date);
  startDT.add(Calendar.DAY_OF_MONTH,(int)t+1);
  return startDT.getTime();
 }


}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

com.ab.oa.timer.TimerTaskProxy.java如下:

package com.ab.oa.timer;

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

import com.sinosoft.util.logging.LogFactory;
import com.sinosoft.util.logging.Logger;

/**
 *
 * @author uwaysoft
魏韶颖
 *
时间:200942015:02:58
 */
public class TimerTaskProxy extends TimerTask{

 Logger logger = LogFactory.getLogger(TimerTaskProxy.class);
  
 private int count;
 
 private Timer timer;
 
 private int hasExeNum = 0;
 
 private TimerTask timerTask;
 
 /**
  *
定时任务代理调用客户写的子类run方法
  * @param subClassName
子类名
  * @param count
执行多少次
  * @param timer
定时器
  */
 public TimerTaskProxy(String subClassName, int count,Timer timer) {
  super();
  this.count = count;
  this.timer = timer;
  try {
   this.timerTask = (TimerTask)Class.forName(subClassName).newInstance();
  } catch (InstantiationException e) {
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
 }
 
 public void run() {
  /**
   *
运用了多态条件:继承,重写,父类引用指向子类对象所以调用的是子类的run()
   */
  timerTask.run();
  hasExeNum ++;
  if(count == hasExeNum) {
   timer.cancel();
   logger.info("
定时任务执行完毕,线程成功终止!");
  }
 }
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

测试及使用Demo如下:

package com.ab.oa.timer;

import java.util.Random;
import java.util.TimerTask;

/**
 *
定时任务的模板例子:
 *
要使用定时任务只需要:
 * 1.
写一个类继承TimerTask,把要做的任务写到run方法里
 * 2.
按照需求调用不同的构造方法
 * 3.
方法要求写继承了TimerTask的子类全路径名(包名+类名)
 *
 * @author uwaysoft weisy
时间:200942016:36:14
 */
public class MyTask extends TimerTask {

 public void run() {
  // TODO: write you task here
  System.out.println("----
正在执行定时任务编号=" + newRandom().nextInt(10000));
 }

 public static void main(String[] args) {
  
  //
如:从5.1开始每天早上8:30给员工发信息一直发送
  //OpenTask openTask = new OpenTask("2009-05-01 08:30:00",true, 10, 24*60*60*1000);
  
  //
如:从5.1开始每天早上830给员工发信息连续发送一周
  OpenTask openTask = new OpenTask("2009-04-21 08:58:00",false, 10, 1000);
  
  //
如:5.1早上830给员工发信息只发送一次
  //OpenTask openTask = new OpenTask("2009-05-01 08:30:00",false, 1, 1000);
  
  //
如:从5.1开始每天早上830给员工发信息每隔2小时发送一次总共发送5
  //OpenTask openTask = new OpenTask("2009-05-01 08:30:00",false, 1, 2*60*60*1000);
  
  //***************
错误的参数*************
  //OpenTask openTask = new OpenTask("2009-05-01 08:30:00",false, 0, 2*60*60*1000);
  //OpenTask openTask = new OpenTask("2009-05-01 08:30:00",false, 2, -2*60*60*1000);
  //************************************
  
  openTask.openTimerTask("com.ab.oa.timer.MyTask");
 }
}

///

特定时间执行

import java.util.Date;

import java.util.Timer;

import java.util.TimerTask;

 

public class Test{

 public static voidmain(String[] args) {

  Timer t = newTimer();

  Date date = newDate();

  date.setHours(8);

  //1.特定时间运行,注意,这里不能每天都执行,你要根据实际情况做修改

  t.schedule(newMyTask(), date);

 date.setHours(12);

  t.schedule(newMyTask(), date);

 date.setHours(14);

  t.schedule(newMyTask(), date);

  //2.间隔一定时间段运行一次,这里是每5秒

  t.schedule(newMyTask(), date, 5000); 

 }

}

class MyTask extends TimerTask {

 public void run(){

 System.out.println("run!");

 }

}

 

///

Timer timer = new Timer();

timer.schedule(new MyTask(), firstTime, 24*60*60*1000L);

timer.schedule(new MyTask(), secondTime,24*60*60*1000L);

timer.schedule(new MyTask(),ThirdTime, 24*60*60*1000L);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值