定时器Timer

昨夜星辰昨夜风,画楼西畔桂堂东
在JDK库中,Timer类主要负责计划任务的功能,也就是在指定时间开始执行某一个任务,Timer类方法列表如下所示:
这里写图片描述
Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类,类结构如下所示:
这里写图片描述
执行计划任务的代码要放入TimerTask的子类中,因为TimerTask是一个抽象类。
下面介绍并测试几个常用的方法:

  • 方法schedule(TimerTask task, Date time):该方法的作用是在指定的日期执行一次某一任务。
    测试代码:

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;


public class TimerTest {
    public static void main(String[] args) {
        System.out.println("当前时间为:" + new Date());
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND , 10);     //设置时间为10秒之后
        Date time = instance.getTime();

        MyTask myTask = new MyTask();
        Timer timer = new Timer();
        timer.schedule(myTask,time);
    }
}

class MyTask extends TimerTask {

    @Override
    public void run() {
        System.out.println("任务执行时间:" + new Date());
    }
}

运行结果:
这里写图片描述
但是这里,你应该注意到,任务已经执行了,但是程序还没有停下来。我们来看下在创建Timer对象时的源码:

 /**
     * Creates a new timer.  The associated thread does <i>not</i>
     * {@linkplain Thread#setDaemon run as a daemon}.
     */
    public Timer() {
        this("Timer-" + serialNumber());
    }
    //这个构造方法调用的是如下的构造方法
        /**
     * Creates a new timer whose associated thread has the specified name.
     * The associated thread does <i>not</i>
     * {@linkplain Thread#setDaemon run as a daemon}.
     *
     * @param name the name of the associated thread
     * @throws NullPointerException if {@code name} is null
     * @since 1.5
     */
    public Timer(String name) {
        thread.setName(name);
        thread.start();
    }

由此可知,创建一个Timer就是启动了一个线程,由于这个启动的线程不是守护线程,所以一直在运行。下面将新创建的Timer类改成守护线程:
只需要将上面的 Timer timer = new Timer();改为 Timer timer = new Timer(true);即可,再来看看运行结果:
这里写图片描述
可以看到,程序运行后迅速结束了当前的线程,并且TimerTask中任务也没有被运行,因为进程已经结束。
并且,如果计划的时间早于当前时间,则立即执行task任务;

  • 方法 schedule(TimerTask task, Date firstTime,long period):该方法的作用是在指定的日期之后按指定的间隔周期,无线循环的执行某一任务。
    测试代码:

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;


public class TimerTest {
    public static void main(String[] args) {
        System.out.println("当前时间为:" + new Date());
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND , 10);     //设置时间为10秒之后
        Date time = instance.getTime();

        MyTask myTask = new MyTask();
        Timer timer = new Timer();
        timer.schedule(myTask,time,2000);
    }
}

class MyTask extends TimerTask {

    @Override
    public void run() {
        System.out.println("任务执行时间:" + new Date());
    }
}

运行结果:
这里写图片描述
从运行结果可以看出,任务每2秒被执行一次,而且还是无限期重复执行的。

  • 方法 schedule(TimerTask task,long delay):该方法的作用是以执行schedule(TimerTask task,long delay)方法当前的时间为参考时间,在此基础上延迟指定的毫秒数后执行一次TimerTask任务。
    测试代码:

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimerTest {
    public static void main(String[] args) {
        System.out.println("当前时间为:" + new Date());
//        Calendar instance = Calendar.getInstance();
//        instance.add(Calendar.SECOND , 10);     //设置时间为10秒之后
//        Date time = instance.getTime();

        MyTask myTask = new MyTask();
        Timer timer = new Timer();
        timer.schedule(myTask,2000);
    }
}

class MyTask extends TimerTask {

    @Override
    public void run() {
        System.out.println("任务执行时间:" + new Date());
    }
}

运行结果:
这里写图片描述
由此可知,任务被延迟2秒执行了。

  • 方法schedule(TimerTask task,long delay,long period):该方法的作用是以执行schedule(TimerTask task,long delay,long period)方法当前的时间为参考时间,在此时间基础上延迟指定的毫秒数,再以某一间隔时间无限次数地执行某一任务。
    测试代码:


import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;


public class TimerTest {
    public static void main(String[] args) {
        System.out.println("当前时间为:" + new Date());
//        Calendar instance = Calendar.getInstance();
//        instance.add(Calendar.SECOND , 10);     //设置时间为10秒之后
//        Date time = instance.getTime();

        MyTask myTask = new MyTask();
        Timer timer = new Timer();
        timer.schedule(myTask,3000,2000);
    }
}

class MyTask extends TimerTask {

    @Override
    public void run() {
        System.out.println("任务执行时间:" + new Date());
    }
}

运行结果:
这里写图片描述
在当前时间3秒过后,以每2秒的周期执行任务。

  • 方法scheduleAtFixedRate(TimerTask task,Date firstTime,long period):方法scheduleAtFixedRate和schedule主要的区别只在于有没有追赶特性:

验证schedule方法不具备追赶执行性,测试代码:


import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;


public class TimerTest {
    public static void main(String[] args) {
        MyTask myTask = new MyTask();
        System.out.println("当前时间为:" + new Date());
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.SECOND , instance.get(Calendar.SECOND) -10);     //设置时间为10秒之前
        Date time = instance.getTime();

        System.out.println("计划执行时间:" + time);
        Timer timer = new Timer();
        timer.schedule(myTask,time,2000);
    }
}

class MyTask extends TimerTask {

    @Override
    public void run() {
        System.out.println("begin time" + new Date());
        System.out.println("end time" + new Date());
    }
}

运行结果:
这里写图片描述
从时间上可以看出来,59分10秒到59分20秒之间的任务都没有执行,所以,schedule不具备追赶特性。
验证scheduleAtFixedRate有追赶特性,测试代码:


import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;


public class TimerTest {
    public static void main(String[] args) {
        MyTask myTask = new MyTask();
        System.out.println("当前时间为:" + new Date());
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.SECOND , instance.get(Calendar.SECOND) -10);     //设置时间为10秒之前
        Date time = instance.getTime();

        System.out.println("计划执行时间:" + time);
        Timer timer = new Timer();
//        timer.schedule(myTask,time,2000);
        timer.scheduleAtFixedRate(myTask,time,2000);
    }
}

class MyTask extends TimerTask {

    @Override
    public void run() {
        System.out.println("begin time" + new Date());
        System.out.println("end time" + new Date());
    }
}

运行结果:
这里写图片描述
可以看出,在01分44秒到01分54秒之间的任务都被“补充性”的执行了,所以,scheduleAtFixedRate具备追赶特性。

猜你喜欢

转载自blog.csdn.net/a_runner/article/details/80715858