Timer

来源:互联网 发布:node.js怎么循环输出 编辑:程序博客网 时间:2024/05/21 11:21
/*
定时器Timer--内部使用多线程方式处理
在指定的时间开始执行某一个任务;执行计划任务的代码要放入TimerTask的子类中(需要执行具体的什么任务放在这块),因为TimerTask是一个抽象类
1:schedule(TimerTask task,Date time)在指定的日期执行一次某一任务


首先需要设计一个TimerTask的子类
public class MyTask extends TimerTask{
public void run(){
System.out.println("我是需要执行的定时任务"+new Date());
}
然后设计可以执行的代码,但是任务还未销毁,呈红色状态,因为创建一个Timer就是启动一个线程,这个线程
不是守护线程,所以会一直运行;如果将Timer改成守护线程即:Timer timer = new Timer(true);则打印完
当前时间就停止了,不会执行task的任务
public static void main(String args[]){
System.out.println("当前时间为"+new Date());
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND,10);//执行完当前时间之后,未来的10s执行
//calendar.set(Calendar.SECOND,calendar.get(calendar)-10);在执行完当前任务之前10s运行,但任务会顺序执行,并不会像想像的那样
Date date = calendar.getTime();

MyTask task = new MyTask();
Timer timer = new Timer();
timer.schedule(task,date);
}
如果有多个TimerTask任务及延时测试,则以队列的方式一个一个被顺序性地执行,因为前面的任务有可能可能消耗的时间较长
所以执行的时间和预期的时间很可能不一致
 
 2:方法schedule(TimerTask task,Date firstTime,long period)在指定的日期之后按指定的间隔周期,无限循环的执行某一任务
首先需要设计一个TimerTask的子类
public class MyTask extends TimerTask{
public void run(){
System.out.println("我是需要执行的定时任务"+new Date());
}
public static void main(String args[]){
System.out.println("当前时间为"+new Date());
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND,10);//执行完当前时间之后,未来的10s执行
Date date = calendar.getTime();

MyTask task = new MyTask();
Timer timer = new Timer();
timer.schedule(task,date,4000);
打印完当前时间10s后,开始执行任务,每4s执行一次,无限期重复
calendar.set(Calendar.SECOND,calendar.get(calendar)-10);打印完当前时间后,立即执行,每4s执行一次,无限期
即使task里面有sleep(),也要等sleep完才能继续执行
}
 3:TimerTask类的cancel()任务 将自身从任务队列中进行清除
  public class MyTask extends TimerTask{
public void run(){
System.out.println("我是需要执行的定时任务"+new Date());
this.cancel();
System.out.println("我已经移除了自己的定时任务");
}
public static void main(String args[]){
System.out.println("当前时间为"+new Date());
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();

MyTask task = new MyTask();
Timer timer = new Timer();
timer.schedule(task,date,4000);
则只执行一次,就不在循环执行了,其他的TimerTask不受任何影响
}
  4:Timer类的cancel()方法,将任务队列中全部的任务进行清空
  public class MyTaskA extends TimerTask{
public void run(){
System.out.println("我是需要执行的定时任务A"+new Date());
}
}
public class MyTaskB extends TimerTask{
public void run(){
System.out.println("我是需要执行的定时任务B"+new Date());
}
}
public static void main(String args[]){
System.out.println("当前时间为"+new Date());
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();

MyTaskA taskA = new MyTaskA();
MyTaskB taskB = new MyTaskB();
Timer timer = new Timer();
timer.schedule(taskA,date,4000);
timer.schedule(taskB,date,4000);
thread.sleep(10000);
timer.cancel();
只执行10s的循环任务,然后全部任务被清除,并且进程被销毁,按钮由红色变为灰色
注意:Timer的cancel()方法有时不一定会停止计划任务,而是正常执行;因为canel()方法有时没有争抢到queue锁,则让
TimerTask类中的任务正常执行
 5:方法schedule(TimerTask task,long delay)以执行此方法当前的时间为参考时间,在此时间的基础上延迟指定的毫秒数后执行一次TimerTask任务
  public class MyTaskA extends TimerTask{
public void run(){
System.out.println("我是需要执行的定时任务A"+new Date());
}
}
public static void main(String args[]){
MyTaskA taskA = new MyTaskA();
Timer timer = new Timer();
System.out.println("当前时间为"+new Date());
timer.schedule(taskA,7000);
任务被延迟7s执行了
}
 6:方法schedule(TimerTask task,long delay,long period)
       以执行此方法当前的时间为参考时间,在此时间的基础上延迟指定的毫秒数后执行一次TimerTask任务,再以某一时间间隔无限次的执行某一任务
 
 7:方法scheduleAtFixedRate(TimerTask task,Date firstTime,long period)和方法schedule都会顺序的执行,只是scheduleAtFixedRate具有追赶性
  a1:MyTask里面睡1s,主线程timer.schedule(task,马上,3000),没有延时,第一次马上执行,第二次粗略的认为3s执行一次
  b1:MyTask里面睡1s,主线程timer.schedule(task,3000,4000),没有延时,第一次延迟3s执行, 第二次4s后执行
  c1:MyTask里面睡5s,主线程timer.schedule(task,马上,2000),有延时,第一次马上执行,第二次5s后执行
  d1:MyTask里面睡5s,主线程timer.schedule(task,3000,2000),有延时,第一次延迟3s执行,第二次5s后执行
 
  a2:MyTask里面睡1s,主线程timer.scheduleAtFixedRate(task,马上,3000),没有延时,第一次马上执行,第二次粗略的认为3s执行一次
  b2:MyTask里面睡1s,主线程timer.scheduleAtFixedRate(task,3000,4000),没有延时,第一次延迟3s执行, 第二次4s后执行
  c2:MyTask里面睡5s,主线程timer.scheduleAtFixedRate(task,马上,2000),有延时,第一次马上执行,第二次5s后执行
  d2:MyTask里面睡5s,主线程timer.scheduleAtFixedRate(task,3000,2000),有延时,第一次延迟3s执行,第二次5s后执行
 
  这两个方法在运行效果上没有任何区别,但是schedule()方法没有追赶性,scheduleAtFixedRate()方法具有追赶性
 
  static class MyTask extends TimerTask{
public void run() {
System.out.println("begin任务,我的执行时间为"+System.currentTimeMillis());
System.out.println("end任务,  我的执行时间为"+System.currentTimeMillis());
}
}
public static void main(String[] args) {
MyTask myTask = new MyTask();
System.out.println("现在执行时间为"+System.currentTimeMillis());
Calendar c = Calendar.getInstance();
c.set(Calendar.SECOND, c.get(Calendar.SECOND)-20);
System.out.println("计划执行时间为"+c.getTime().getTime());
Timer timer = new Timer();
timer.schedule(myTask,c.getTime(), 1000);
因为需要提前执行,中间有20s的时间差,如果是schelude()方法,则这时间段的任务就不执行了,直接从当前时间开始往下执行
timer.scheduleAtFixedRate(myTask,c.getTime(), 1000);
scheludeFixedRate()方法则要追赶这20s的时间差,以当前时间执行好多次,即时间相同的任务,然后继续往下执行
}
 */