1.0-Timer(小弟)

一.定义

  • 有且仅有一个后台线程对多个业务线程进行定时定频率的调度.

二.简单使用

首先创建TimerTask类,实现业务逻辑的run方法.

private String name;
    public MyTimerTask(String inputname) {
        this.name = inputname;
    }

    public String getName() {
        return name;
    }

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

    public void run() {
        System.out.println("Current name is:" + name);
    }

通过timer调用task来定时定频率的执行

//1.创建一个Timer实例
        Timer timer = new Timer();
        //2.创建一个MyTimerTask实例
        MyTimerTask myTimerTask = new MyTimerTask("No.1");
        //3.通过timer定时定频率调用myTimerTask的业务逻辑
        //第一次执行实在当前时间的两秒后,每隔1秒执行一次.
        timer.schedule(myTimerTask, 2000L, 1000L);

三.schedule的四种用法

1.schedule的前两种用法

a.规定时间后执行一次

//1.创建一个Timer实例
        Timer timer = new Timer();
        //2.创建一个MyTimerTask实例
        MyTimerTask myTimerTask = new MyTimerTask("No.1");
        //3.通过timer定时定频率调用myTimerTask的业务逻辑
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sf.format(calendar.getTime()));
        calendar.add(Calendar.SECOND, 3);
        myTimerTask.setName("schedule1");
        //三秒后执行一次
        timer.schedule(myTimerTask, calendar.getTime());

b.时间等于或超过time首次执行task,之后每隔period毫秒重复执行一次task

//三秒后执行一次,之后每隔2秒重复执行一次task
        timer.schedule(myTimerTask, calendar.getTime(), 2000L);

2.schedule的后两种方法

a.参数不是time而是delay

//三秒后执行一次
        timer.schedule(myTimerTask, 3000L);

b.参数不是time而是delay

//三秒后执行一次,之后每隔2秒重复执行一次task
        timer.schedule(myTimerTask, 3000L,2000L);

四.scheduleAtFixedRate的两种用法

1.time参数

三个参数

  • task - 所安排的任务
  • time - 首次执行任务的时间
  • period - 重复的时间间隔
    timer.scheduleAtFixedRate(task,time,period);

2.delay参数

  • task - 所安排的任务
  • delay- 首次执行任务的时间,距离当前时间多少毫秒
  • period - 重复的时间间隔
    timer.scheduleAtFixedRate(task,delay,period);

五.其他函数

1.TimerTask的cancel(),scheduledExecutionTime()

  • cancel()
    作用:取消当前TimerTask里的任务
思路是在TimerTask列中,创建一个属性,记录重复次数,然后在run()方法中判断这个次数,当想让停止的时候调用cancel()方法.就会取消定时任务.
  • scheduledExecutionTime()
    作用:返回此任务最近实际执行的已安排执行的时间.为long型.

2.Timer的cancel(),purge()

  • cancel()
    作用:终止此计时器,丢弃所有当前已安排的任务.也就是这个Timer下的所有Task都会被取消掉.
  • purge()
    作用:从此计时器的任务队列中移除所有已取消的任务;返回值是移除的任务数.

六.schedule和scheduleAtFixedRate的区别

两种情况看区别

  • 首次计划执行的时间早于当前的时间
    1.schedule方法:如果第一次执行时间被delay了,随后执行的时间按照上一次实际执行完成的时间点进行计算.也就是说如果schedule的第一次执行时间早于现在的时间,那么程序会马上执行一次,然后按传入的时间间隔重复执行.
    2.scheduleAtFixedRate方法:如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,并且为了赶上进度会多次执行任务,因此TimerTask中的执行体要考虑同步.也就是说如果scheduleAtFixedRate的第一次执行时间早于现在时间,那么程序会先把之前那段时间的task任务执行一遍,再来执行当前时间的任务,然后按照传入的时间间隔重复执行.
  • 任务执行所需时间超出任务的执行周期间隔
    1.schedule方法:下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后.
    2.scheduleAtFixedRate方法:下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性.

七.综合应用

跳舞机器人和灌水机器人的例子

  • 跳舞机器人代码
public class DancingRobot extends TimerTask {

    public void run() {
        //获取最近的一次任务执行的时间并将其格式化
        SimpleDateFormat sf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
        System.out.println("Scheduled exec time is:" + sf.format(scheduledExecutionTime()));
        System.out.println("Dancing happily!");
    }
}
  • 灌水机器人
public class WaterRobot extends TimerTask {

    //最大容量为5
    private Integer bucketCapacity = 0;

    private Timer timer;
    public WaterRobot(Timer inputTimer) {
        this.timer = inputTimer;
    }

    public void run() {
        //灌水,直到桶满为止
        if (bucketCapacity < 5) {
            System.out.println("Add 1 water into the bucket!");
            bucketCapacity ++;
        } else {
            //水满就停止执行.
            System.out.println("The number of canceled task in timer is:" + timer.purge());
            cancel();
            System.out.println("The waterRobot has been aborted");
            System.out.println("The number of canceled task in timer is:" + timer.purge());
            System.out.println("Current water is:" + bucketCapacity);
            //等待两秒钟,终止timer里面的所有内容
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            timer.cancel();
            System.out.println("The number of canceled task in timer is:" + timer.purge());
        }

    }
}
  • 执行类
public class Executor {
    public static void main(String[] args) {
        Timer timer = new Timer();
        //获取当前的时间
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
        System.out.println("Current time is:" + sf.format(calendar.getTime()));
        DancingRobot dr = new DancingRobot();
        WaterRobot wr = new WaterRobot(timer);

        timer.schedule(dr, calendar.getTime(), 2000);
        timer.scheduleAtFixedRate(wr, calendar.getTime(), 1000);
    }
}

八.Timer的缺陷

1. 管理并发任务的缺陷

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

2. 任务抛出异常时的缺陷

  • 如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行.

九.Timer的使用禁区

  • 对时效性要求较高的多任务并发作业.
  • 对复杂任务的调度.
  • 这时候需要大哥

你可能感兴趣的:(1.0-Timer(小弟))