定时任务调度工具之Timer(四)

字数 208阅读 88

定时任务调度工具之Timer(四)

一、Timer函数的综合应用

需求:实现两个机器人

第一个机器人会隔两秒打印最近一次计划的时间、执行内容
第二个机器人会模拟往桶里倒水,直到桶里的水满为止

灌水机器人执行流程:

灌水机器人.jpg

跳舞机器人执行流程:

跳舞机器人.jpg

代码演示:

1.创建跳舞机器人

package com.hcx.timer4;

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

/**
 * Created by HCX on 2017/9/4.
 * 跳舞机器人
 */
public class DancingRobot extends TimerTask{
    @Override
    public void run() {
        //获取最近的一次任务执行时间,并将其格式化
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("最近的一次任务执行时间是:"+sf.format(scheduledExecutionTime()));
        System.out.println("跳舞机器人在跳舞");
    }
}

2.创建灌水机器人

package com.hcx.timer4;

import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by HCX on 2017/9/5.
 * 灌水机器人
 */
public class WaterRobot extends TimerTask{

    //桶的最大容量为5L
    private Integer bucketCapacity = 0;
    private Timer timer;

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

    @Override
    public void run() {
        //灌水直至桶满为止
        if(bucketCapacity<5){
            System.out.println("灌水机器人加一升水到桶中");
            bucketCapacity++;
        }else {
            //取消之前打印一次
            System.out.println("timer下被取消的任务数量是:" + timer.purge());
            //水满之后就停止执行
            //timerTask的cancel:只是取消单个实例,即取消单个TimerTask实例的任务执行
            cancel();
            System.out.println("灌水机器人已经停止执行了");
            //timer.purge():返回timer下面的已被取消的任务数,本身的作用是移除已被取消的timertask实例的内存
            //取消之后打印一次
            System.out.println("timer下被取消的任务数量是:" + timer.purge());
            //打印当前的水容量
            System.out.println("当前的水容量是:" + bucketCapacity + "L");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //Timer的cancel,取消timer实例下面的所有计划的task的执行
            timer.cancel();
        }
    }
}

3.创建执行类

package com.hcx.timer4;

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

/**
 * Created by HCX on 2017/9/5.
 * 执行类
 */
public class Executor {
    public static void main(String[] args){
        Timer timer = new Timer();
        //获取当前时间
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("当前时间为:" + 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);

        /**
         * 实现当WaterRobot灌满水之后,继续让DancingRobot跳舞2秒钟再停止执行
         */
    }
}

运行结果:

当前时间为:2017-09-05 16:01:37
最近的一次任务执行时间是:2017-09-05 16:01:37
跳舞机器人在跳舞
灌水机器人加一升水到桶中
灌水机器人加一升水到桶中
灌水机器人加一升水到桶中
最近的一次任务执行时间是:2017-09-05 16:01:39
跳舞机器人在跳舞
灌水机器人加一升水到桶中
灌水机器人加一升水到桶中
最近的一次任务执行时间是:2017-09-05 16:01:41
跳舞机器人在跳舞
timer下被取消的任务数量是:0
灌水机器人已经停止执行了
timer下被取消的任务数量是:1
当前的水容量是:5L

Process finished with exit code 0

二、Timer的缺陷

1.管理并发任务的缺陷

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

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

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

Timer的使用禁区:
(1)对时效性要求较高的多任务并发作业
(2)对复杂任务的调度

推荐阅读更多精彩内容