定时器Timer

来源:互联网 发布:卖鞋用的销售软件 编辑:程序博客网 时间:2024/06/05 08:55

定时器Timer的使用

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

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

package me.mymilkbottles.Study10;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;/** * Created by Administrator on 2017/07/17 13:29. */public class TimerStudy {    private static final Timer timer = new Timer();    public static void main(String[] args) throws ParseException {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        System.out.println("now time " + new Date().toLocaleString());        Date date = sdf.parse("2017-07-17 13:53:30");        System.out.println("should time " + date.toLocaleString());        timer.schedule(new MyTask(), date);        System.out.println("finish " + new Date().toLocaleString());    }}class MyTask extends TimerTask {    @Override    public void run() {        System.out.println("execute start " + new Date().toLocaleString());        try {            Thread.sleep(5000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("execute end " + new Date().toLocaleString());    }}

任务执行完毕,但是程序并没有结束,因为创建一个Timer就是启动一个新的线程,这个新启动的线程并不是守护线程,它一直在运行。

所以我们将其改为守护线程:

private static final Timer timer = new Timer(true);

但是这样设置的话,程序运行之后迅速结束当前的进程,并且TimerTask的任务也不再被执行,因为进程已经结束了。

1、如果执行任务的时间晚于当前时间,那么就会在设置执行任务的时间执行

2、如果执行任务的时间早于当前时间,那么就会立刻执行

TimerTask是以队列的方式一个一个被顺序执行的,所以执行的时间有可能和预期的时间不一致,因为前面有可能消耗的时间较长,则后面的任务运行的时间也会被延迟。

package me.mymilkbottles.Study10;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;/** * Created by Administrator on 2017/07/17 13:29. */public class TimerStudy01 {    private static final Timer timer = new Timer();    public static void main(String[] args) throws ParseException {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        System.out.println("now time " + new Date().toLocaleString());        Date date = new Date(new Date().getTime() + 3000);        System.out.println("task should time " + date.toLocaleString());        timer.schedule(new MyTask(), date);        Date date1 = new Date(new Date().getTime() + 4000);        System.out.println("task1 should time " + date1.toLocaleString());        timer.schedule(new MyTask1(), date1);        System.out.println("finish " + new Date().toLocaleString());    }}class MyTask extends TimerTask {    @Override    public void run() {        System.out.println("task execute start " + new Date().toLocaleString());        try {            Thread.sleep(5000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("task execute end " + new Date().toLocaleString());    }}class MyTask1 extends TimerTask {    @Override    public void run() {        System.out.println("task1 execute start " + new Date().toLocaleString());        try {            Thread.sleep(15000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("task1 execute end " + new Date().toLocaleString());    }}/*执行时间:now time 2017-7-17 14:15:38task should time 2017-7-17 14:15:41task1 should time 2017-7-17 14:15:42finish 2017-7-17 14:15:38task execute start 2017-7-17 14:15:41task execute end 2017-7-17 14:15:46task1 execute start 2017-7-17 14:15:46task1 execute end 2017-7-17 14:16:01*/
package me.mymilkbottles.Study10;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;/** * Created by Administrator on 2017/07/17 13:29. */public class TimerStudy02 {    private static final Timer timer = new Timer();    public static void main(String[] args) throws ParseException {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        System.out.println("now time " + new Date().toLocaleString());        Date date = new Date(new Date().getTime() + 3000);        System.out.println("task should time " + date.toLocaleString());        timer.schedule(new MyTask(), date, 2000);        System.out.println("finish " + new Date().toLocaleString());    }}

方法timer.schedule(new MyTask(), date, 2000);的作用就是在指定的日期后,按指定的间隔周期性地无限循环的执行某一任务。
如果计划时间早于当前时间,则立即执行。如果任务执行的时间超过了指定的间隔时间,则下一次任务执行的时间将会滞后。

package me.mymilkbottles.Study10;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;/** * Created by Administrator on 2017/07/17 13:29. */public class TimerStudy02 {    private static final Timer timer = new Timer();    public static void main(String[] args) throws ParseException, InterruptedException {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        System.out.println("now time " + new Date().toLocaleString());        Date date = new Date(new Date().getTime() - 2000);        System.out.println("task should time " + date.toLocaleString());        TimerTask task = new MyTask();        timer.schedule(task, date, 2000);        System.out.println("finish " + new Date().toLocaleString());        Thread.sleep(12000);        System.out.println("task cancel");        task.cancel();    }}

TimerTask的cancel方法的作用是将自身任务从任务队列中移出。如果任务还没有执行完,则会将剩下的任务执行完。

package me.mymilkbottles.Study10;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;/** * Created by Administrator on 2017/07/17 13:29. */public class TimerStudy02 {    private static final Timer timer = new Timer();    public static void main(String[] args) throws ParseException, InterruptedException {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        System.out.println("now time " + new Date().toLocaleString());        Date date = new Date(new Date().getTime() - 2000);        System.out.println("task should time " + date.toLocaleString());        TimerTask task = new MyTask();        timer.schedule(task, date, 2000);        System.out.println("finish " + new Date().toLocaleString());        Thread.sleep(12000);        System.out.println("task cancel");        timer.cancel();    }}

Timer类中的cancel方法的作用是将任务队列中的全部任务清空,并且进程被销毁。

方法schedule和方法scheduleAtFixedRate都会按顺序执行,所以不需要考虑线程安全问题。

使用schedule方法:
如果执行任务的时间没有被延时,那么下一次任务的执行时间参考的是“开始”时的时间来计算。

使用scheduleAtFixedRate方法:如果执行任务的时间没有被延时,那么下一次任务的执行时间参考的是上一次任务的结束时间来计算。

延时的情况都是没有区别的,两者下一次任务的执行时间参考的是上一次任务结束的时间计算。

schedule方法不具有追赶性,而scheduleAtFixedRate方法具有追赶执行性,如果计划时间早于当前时间,则这段时间内的Task任务会被“补充性”执行。

原创粉丝点击