美文网首页
1.0-Timer(小弟)

1.0-Timer(小弟)

作者: 王子也寂寞 | 来源:发表于2017-12-09 00:08 被阅读0次

    一.定义

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

    二.简单使用

    首先创建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(小弟)

          本文链接:https://www.haomeiwen.com/subject/hdoyixtx.html