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

java定时任务调度工具之Timer

2017-07-26 08:59 537 查看
一、定义:(祥见JDK文档)有且仅有一个后台线程对多个业务线程进行定时定频率的调度。

二、构件:Timer定时调用,TimerTask任务。

三、timer的schedule函数的四种用法:

       1.schdule(task,time)

              task:所要安排的任务。

             time:执行任务的时间。

             作用:在时间等于或者超过time的时候执行且仅执行一次task(当time晚于当前时间,后台线程等待,当time早于当前时间,启动后立即执行)。

       2.schdule(task,time,period)

              task:所要安排的任务。

              time:执行任务的时间。

              period:执行一次任务的时间间隔,单位是毫秒。

             作用:在时间等于或者超过time的时候首次执行task,之后每隔period毫秒重复执行一次task。
      3.schdule(task,delay)

              task:所要安排的任务。

             time:执行任务前的延迟时间,单位毫秒。

             作用:等待delay毫秒后执行且仅执行一次task。

       4.schdule(task,delay,period)

              task:所要安排的任务。

              delay:执行任务前的延迟时间,单位毫秒。

              period:执行一次任务的时间间隔,单位是毫秒。

             作用:等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task。
      5.schduleAtFixedRate(task,time,period)

              task:所要安排的任务。

              time:执行任务的时间。

              period:执行一次任务的时间间隔,单位是毫秒。

             作用:在时间等于或者超过time的时候首次执行task,之后每隔period毫秒重复执行一次task。
     6.schduleAtFixedRate(task,time,period)

              task:所要安排的任务。

              time:执行任务的时间。

              period:执行一次任务的时间间隔,单位是毫秒。

             作用:等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task。

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;

public class MytimerTask extends TimerTask{
private String name;//任务名称
private AtomicInteger count = new AtomicInteger(0);//执行次数,线程安全
public MytimerTask(String name){
this.name = name;
}
public void run() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String time = format.format(calendar.getTime());

//已安排的任务最近执行时间
long nexttime = scheduledExecutionTime();
System.out.println(name+"最近执行时间时间:"+ format.format(nexttime));
//获取当前的值并自增
count.getAndIncrement();
System.out.println("执行"+count+"次"+name+"任务:"+ time);

if(count.get()>=5){
System.out.println("----"+name+"执行任务满五次取消任务----");
//取消当前timerTask里面的任务
cancel();
}

}

}

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

public class Mytimer{

public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
TimerTask myTask1 = new MytimerTask("myTask1");

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

//获取当前时间
Calendar calendar = Calendar.getInstance();
System.out.println("启动定时器时间:"+dateFormat.format(calendar.getTime()));
//当前时间的三秒钟后
calendar.add(Calendar.SECOND, 3);
//在时间等于或超过time的时候执行且仅执行一次任务
timer.schedule(myTask1, calendar.getTime());

TimerTask myTask2 = new MytimerTask("myTask2");

Thread.sleep(5000);//休眠5s
//在时间等于或在超过time时,首次执行task,之后每隔period毫秒,重复执行一次task
timer.schedule(myTask2, calendar.getTime(), 3000);

TimerTask myTask3 = new MytimerTask("myTask3");
//等待delay毫秒后,执行且仅执行一次task
timer.schedule(myTask3, 2000);

//在等待delay毫秒后,首次执行task,之后每隔period毫秒,重复执行一次task
TimerTask myTask4 = new MytimerTask("myTask4");
timer.schedule(myTask4, 3000, 2000);

Thread.sleep(5000);//休眠5s

//在时间等于或在超过time时,首次执行task,之后每隔period毫秒,重复执行一次task
TimerTask myTask5 = new MytimerTask("myTask5");
timer.scheduleAtFixedRate(myTask5, calendar.getTime(), 2000);

//在延迟delay毫秒后,首次执行task,之后每隔period毫秒执行一次task
TimerTask myTask6 = new MytimerTask("myTask6");
timer.scheduleAtFixedRate(myTask6, 2000, 3000);

//从此计时器的任务队列中移除所有已取消的任务
timer.purge();

//丢弃当前所有已安排的任务
timer.cancel();

System.out.println("所有任务取消");

}

}

scheduleAtFixedRate与schedule的区别:

    1.首次计划执行时间早于任务启动时间

           schedule方法:如果第一次执行时间被延迟了,随后的执行时间按照上一次实际执行完成的时间点进行计算

           scheduleAtFixedRate方法:如果第一次执行时间被延迟了,随后执行时间按照上一次开始时间点进行计算,并且为了赶上进度,会多次执行任务,因此TimerTask中的执行体需要考虑同步。

     2.执行任务时间超出执行周期的间隔

         schedule 方法:下一次执行时间相对于上一次实际完成的时间点,因此执行时间会不断延后

        scheduleAtFixedRate方法:下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性

         

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

public class Mytimer{

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

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

//获取当前时间
Calendar calendar = Calendar.getInstance();
System.out.println("启动定时器时间:"+dateFormat.format(calendar.getTime()));
//当前时间的四秒钟之前
calendar.add(Calendar.SECOND, -4);

TimerTask myTask1 = new MytimerTask("myTask1");
timer.schedule(myTask1, calendar.getTime(), 2000);

TimerTask myTask2 = new MytimerTask("myTask2");
timer.scheduleAtFixedRate(myTask2, calendar.getTime(), 2000);

}

}
   timer的缺陷:

    1. 管理并发任务的缺陷: timer有且仅有一个后台线程去执行定时任务,如果存在多个任务,且任务时间过长会导致执行效果与预期不符。

    2.当任务抛出异常时的缺陷:如果TimerTask抛出RuntimeException,timer会停止所有任务的运行

Timer的使用禁区:

   1.对时效性要求较高的任务并发作业

   2.对复杂任务的调度
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: