Timer定时器

2018-05-25  本文已影响4人  onlyHalfSoul

主要两个要点:

定时器Timer的使用

JDK中Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某个任务。

Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类。

执行计划任务的代码要放入TaskTimer的子类中,因为TimerTask是一个抽象类。

方法schedule(TimerTask task, Date time)的测试

schedule()方法的作用是在指定的日期执行一次某任务。

public class Run1 {

    /** Field timer */
    private static Timer timer = new Timer();

    /**
     * Method main
     *
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            MyTask           task       = new MyTask();
            SimpleDateFormat sdf        = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String           dateString = "2018-05-03 19:59:00";
            Date             dateRef    = sdf.parse(dateString);

            System.out.println("字符串时间,:" + dateRef.toLocaleString() + " 当前时间:" + new Date().toLocaleString());
            timer.schedule(task, dateRef);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * Class MyTask
     *
     *
     * @version        1.0, 18/05/03
     * @author         tz    
     */
    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("运行了,时间为:" + new Date());
        }
    }
} 

/*result:
字符串时间,:2018-5-3 19:59:00 当前时间:2018-5-3 20:01:12
运行了,时间为:Thu May 03 20:01:12 CST 2018
*/

程序运行结束,但进程还未被销毁。

创建一个Timer就是启动一个新线程,这个新启动的线程并不是守护进程,会一直运行下去。

也可以在Timer创建时1改为守护进程。代码如下:

public class Run1TimerDaemon {

    /** Field timer */
    private static Timer timer = new Timer(true);

    /**
     * Method main
     *
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            MyTask           task       = new MyTask();
            SimpleDateFormat sdf        = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String           dateString = "2018-05-04 08:46:00";
            Date             dateRef    = sdf.parse(dateString);

            System.out.println("字符串时间:" + dateRef.toLocaleString() + "当前时间:" + new Date().toLocaleString());
            timer.schedule(task, dateRef);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * Class MyTask
     *
     *
     * @version        1.0, 18/05/04
     * @author         tz
     */
    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("运行了!时间为:" + new Date());
        }
    }
}


/*result:
字符串时间:2018-5-4 8:46:00当前时间:2018-5-4 8:46:49
*/

程序运行后迅速结束当前进程,并且TimerTask中任务不再被运行,因为进程已经结束。

如果执行任务时间早于当前时间,则立即执行task任务。

Timer中允许有多个TimerTask任务。TimerTask是以队列的方式一个一个被执行的,所以执行那个时间爱你有可能和预期时间不一致,因为前面的任务有可能消耗较长时间。

public class Run2Later {

    /** Field timer */
    private static Timer timer = new Timer();

    /**
     * Method main
     *
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            MyTask1          task1       = new MyTask1();
            MyTask2          task2       = new MyTask2();
            SimpleDateFormat sdf1        = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sdf2        = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String           dateString1 = "2018-05-04 14:30:00";
            String           dateString2 = "2018-05-04 14:32:00";
            Date             dateRef1    = sdf1.parse(dateString1);
            Date             dateRef2    = sdf2.parse(dateString2);

            System.out.println("字符串1时间:" + dateRef1.toLocaleString() + " 当前时间:" + new Date());
            System.out.println("字符串2时间:" + dateRef2.toLocaleString() + " 当前时间:" + new Date());
            timer.schedule(task1, dateRef1);
            timer.schedule(task2, dateRef2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * Class MyTask1
     *
     *
     * @version        1.0, 18/05/04
     * @author        tz
     */
    public static class MyTask1 extends TimerTask {
        @Override
        public void run() {
            try {
                System.out.println("1 begin 运行了,时间为:" + new Date());
                Thread.sleep(20000);
                System.out.println("1    end 运行了,时间为" + new Date());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * Class MyTask2
     *
     *
     * @version        1.0, 18/05/04
     * @author         tz
     */
    public static class MyTask2 extends TimerTask {
        @Override
        public void run() {
            System.out.println("2 begin 运行了,时间为:" + new Date());
            System.out.println("2 运行了,运行时间为:" + new Date());
            System.out.println("2    end 运行了,时间为" + new Date());
        }
    }
}


/*result:
字符串1时间:2018-5-4 14:30:00 当前时间:Fri May 04 14:37:59 CST 2018
字符串2时间:2018-5-4 14:32:00 当前时间:Fri May 04 14:37:59 CST 2018
1 begin 运行了,时间为:Fri May 04 14:37:59 CST 2018
1    end 运行了,时间为Fri May 04 14:38:19 CST 2018
2 begin 运行了,时间为:Fri May 04 14:38:19 CST 2018
2 运行了,运行时间为:Fri May 04 14:38:19 CST 2018 
2    end 运行了,时间为Fri May 04 14:38:19 CST 2018
*/

方法schedule(TimerTask task, Date firstTime, long period)

该方法的作用是在指定日期之后,按指定的间隔周期性的无限循环某一任务。

public class Run {

    /**
     * Method main
     *
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            MyTask           task       = new MyTask();
            SimpleDateFormat sdf        = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String           dateString = "2018-05-04 14:48:00";
            Timer            timer      = new Timer();
            Date             dateRef    = sdf.parse(dateString);

            System.out.println("字符串时间:" + dateRef.toLocaleString() + " 当前时间:" + new Date().toLocaleString());
            timer.schedule(task, dateRef, 4000);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * Class MyTask
     *
     *
     * @version        1.0, 18/05/04
     * @author         tz
     */
    public static class MyTask extends TimerTask {
        @Override
        public void run() {
            System.out.println("运行了! 时间为:" + new Date());
        }
    }
}

/*result:
字符串时间:2018-5-4 14:48:00 当前时间:2018-5-4 14:53:30
运行了! 时间为:Fri May 04 14:53:30 CST 2018
运行了! 时间为:Fri May 04 14:53:34 CST 2018
运行了! 时间为:Fri May 04 14:53:38 CST 2018
运行了! 时间为:Fri May 04 14:53:42 CST 2018
*/

task以周期为4s的状态下一直运行。

TimerTask的cancel方法

TimerTask的cancel方法是将自身从任务队列中清除掉。

public class Run2 {

    /**
     * Method main
     *
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            MyTaskA          task1      = new MyTaskA();
            MyTaskB          task2      = new MyTaskB();
            SimpleDateFormat sdf        = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String           dateString = "2018-05-04 14:48:00";
            Timer            timer      = new Timer();
            Date             dateRef    = sdf.parse(dateString);

            System.out.println("字符串时间:" + dateRef.toLocaleString() + " 当前时间:" + new Date().toLocaleString());
            timer.schedule(task1, dateRef, 4000);
            timer.schedule(task2, dateRef, 4000);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * Class MyTask
     *
     *
     * @version        1.0, 18/05/04
     * @author         tz
     */
    public static class MyTaskA extends TimerTask {
        @Override
        public void run() {
            System.out.println("A 运行了! 时间为:" + new Date());
            this.cancel();
        }
    }


    /**
     * Class MyTaskB
     *
     *
     * @version        1.0, 18/05/04
     * @author         tz
     */
    public static class MyTaskB extends TimerTask {
        @Override
        public void run() {
            System.out.println("B 运行了! 时间为:" + new Date());
        }
    }
}


/*result:
字符串时间:2018-5-4 14:48:00 当前时间:2018-5-4 15:10:18
A 运行了! 时间为:Fri May 04 15:10:18 CST 2018
B 运行了! 时间为:Fri May 04 15:10:18 CST 2018
B 运行了! 时间为:Fri May 04 15:10:22 CST 2018
B 运行了! 时间为:Fri May 04 15:10:26 CST 2018
B 运行了! 时间为:Fri May 04 15:10:30 CST 2018
*/

Timer的cancel方法

Timer的cancel方法是清除所有的任务队列。

因为Timer的cancel()方法有时候并没有争抢到队列锁,所以TimerTask类中的任务会继续正常执行。

方法schedule(TimerTask task, long delay, long period)

该方法的作用是执行schedule(TimerTask task, long delay, long period)方法当前的时间为参考时间,在此时间的基础上延迟指定的毫秒数,再以某一时间间隔无限制的执行下去。

凡是方法中带有period参数的,都是无限循环执行TimerTask任务。

方法scheduleFixRate(TimerTask task, Date firstTime, long period)

方法scheduleFixRate(TimerTask task, Date firstTime, long period)和schedule()的区别在于不延时的情况。

使用schedule方法,如果执行任务的时间没有延迟,但下一任务的执行时间参考的是上一次任务的“开始”时间。

使用scheduleFixRate方法,参考的则是上一任务的“结束”时间。

上一篇下一篇

猜你喜欢

热点阅读