您的位置:首页 > 编程语言 > Java开发

Java定时任务调度工具详解之Timer篇

2018-03-23 22:40 696 查看
Java定时任务调度工具详解之Timer篇

一,Timer简介

二,Timer的其他重要函数

三,Timer定时任务运用实例

四,Timer的缺陷

参考文档

Java定时任务调度工具详解之Timer篇

定时调度任务是基于给点的时间点,给定的时间间隔或者给定的执行次数自动执行的任务,在java中主要的定时调度工具有JDK原生的定时任务调度工具:Timer和TimerTask;

JDK对定时任务调度的线程池支持:ScheduledExecutorService;

复杂定时任务调度框架:定时任务大哥Quartz;

本文主要分析详解第一种基础的定时调度任务工具Timer和TimerTask,后面两种将在后续的博文中推出

一,Timer简介

使用Timer类进行任务调度,有且仅有一个后台线程对多个业务线程进行定时定频率的调度,这句话说明了Timer的定义,同时也说出了他的缺点,那就是只能有一个后台线程,不能满足并发任务调度的需要;主要流程是使用Timer类定时调用TimerTask来执行任务,TimerTask继承了Runnable接口故需要重写他的run方法,任务代码则就在run方法里,话不多说,先上一段代码>>

package com.wtt.firm;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class TestTimer extends TimerTask{
@Override
public void run() {
Calendar calendar =Calendar.getInstance();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(" Current execute time is  "+sf.format(calendar.getTime()));
}

public static void main(String[] args) {
Timer timer=new Timer();
Calendar calendar =Calendar.getInstance();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(" Current time is "+ sf.format(calendar.getTime()));
TestTimer task = new TestTimer();
//第一种 time.schedule(task,time)  task 为任务,time为执行的时间
timer.schedule(new TestTimer(),calendar.getTime());
//第二种 time.schedule(task,time,period) time为首次执行的时间,period为执行的间隔时间
//timer.schedule(new TestTimer(), calendar.getTime(),60000);
//第三种,
//timer.schedule(new TestTimer(), 2000);
//第四种用法
//timer.schedule(new TestTimer(), 2000, 2000);
//第五种
//timer.scheduleAtFixedRate(new TestTimer(), 1000, 3000);
//第六种
//timer.scheduleAtFixedRate(task,calendar.getTime(),4000);
}


这里说一下Timer的schedule和shceduleAtFixedRate两个方法的区别

- scheduleAtFixedRate:每次执行时间为上一次任务开始起向后推一个period间隔,也就是说下次执行时间相对于上一次任务开始的时间点,因此执行时间不会延后,但是存在任务并发执行的问题。

- schedule:每次执行时间为上一次任务结束后推一个period间隔,也就是说下次执行时间相对于上一次任务结束的时间点,因此执行时间会不断延后。

二,Timer的其他重要函数

TimeTask类

cancel():取消当前TimerTask里的任务

scheduledExecutionTime():返回次任务最近实际执行的已安排执行时间

Timer类

cancel():停止Timer的所有任务;

purge(): 从此计时器的任务队列中清除已取消的任务的内存,返回停止的任务数

package com.wtt.firm;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class TestTimer extends TimerTask{

private String name;

private Integer count=0;

public TestTimer(){};

public  TestTimer (String inputName){
name = inputName;
};

@Override
public void run() {
if(count<3){
Calendar calendar =Calendar.getInstance();

SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

System.out.println(" Current execute time is  "+sf.format(calendar.getTime()));
count++;
}else{
cancel();
System.out.println(" The task cancel!");
}

}

public static void main(String[] args) {
Timer timer=new Timer();

Calendar calendar =Calendar.getInstance();

SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(" Current time is "+ sf.format(calendar.getTime()));

calendar.add(Calendar.SECOND,20);
System.out.println(" The time to execute this task is "+sf.format(calendar.getTime()));

TestTimer task = new TestTimer();
//第一种 time.schedule(task,time)  task 为任务,time为执行的时间
//timer.schedule(new TestTimer(),calendar.getTime());
//第二种 time.schedule(task,time,period) time为首次执行的时间,period为执行的间隔时间
//timer.schedule(new TestTimer(), calendar.getTime(),60000);
//第三种,
//timer.schedule(new TestTimer(), 2000);
//第四种用法
//timer.schedule(new TestTimer(), 2000, 2000);
//第五种
//timer.scheduleAtFixedRate(new TestTimer(), 1000, 3000);
//第六种
timer.scheduleAtFixedRate(task,calendar.getTime(),4000);

System.out.println(" The last time to execute "+sf.format(task.scheduledExecutionTime()));
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getCount() {
return count;
}

public void setCount(Integer count) {
this.count = count;
}
}


三,Timer定时任务运用实例

下面是一个实际例子,用Timer类来执行两个任务

第一个Task任务:

package com.wtt.firm;

import java.text.SimpleDateFormat;
import java.util.TimerTask;

public class DancingRobot extends TimerTask {

@Override
public void run() {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("The time the DancingRobot executing is  "+sf.format(scheduledExecutionTime()));
System.out.println(" dancing happpened ");

}

}


第二个Task任务:

package com.wtt.firm;

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

public class WaterRobot extends TimerTask{

private Timer timer;

private Integer num =  0;

public WaterRobot (Timer inputTimer){
timer = inputTimer;
}

//num为5时停止次任务
@Override
public void run() {

if(num<5){
System.out.println(" add 1L water into the bucket !");
System.out.println(" the capacity of bucket is "+num);
num++;
}else {
//停止WaterRobot里的任务
cancel();
System.out.println(" WaterRobot has been aborted!");
System.out.println(" The number of canceled task in timer is "+timer.purge());
try {
Thread.sleep(2000);//等待两秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
timer.cancel();//停止timer里所有的任务
}

}

}


Timer的执行类:

package com.wtt.firm;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;

public class Executor {
public static void main(String[] args) {
Timer timer = new Timer();

Calendar calendar = Calendar.getInstance();

SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

System.out.println(" the current time is "+sf.format(calendar.getTime()));

//calendar.add(Calendar.MINUTE,1 );
DancingRobot danceTask = new DancingRobot();
WaterRobot waterTask = new WaterRobot(timer);

timer.schedule(danceTask, calendar.getTime(),2000);
timer.scheduleAtFixedRate(waterTask, calendar.getTime(), 1000);

}

}


四,Timer的缺陷

Timer有天生的两种缺陷

管理并发任务的缺陷

Timer有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符;

当任务抛出异常的缺陷

如果TimerTask抛出RuntimelyException,Timer会停止所有任务的运行;

故Timer类不适用于对时效性要求比较高的多任务并发作业和可能抛出异常的复杂任务的调度

参考文档

定时调度工具

Timer学习总结
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息