Timer使用
Posted 雪山上的蒲公英
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Timer使用相关的知识,希望对你有一定的参考价值。
1. Timer简介
Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次。
通过创建Timer对象,然后调用Timer的schedule方法,将TimerTask实例作为参数,从而实现定时调度TimerTask(其中TimerTask对象要继承TimerTask对象,复写run方法)。
Timer工具类
2.Timer函数的使用
2.1 Timer定时函数
看参数应该很好理解
结合demo进行展示(第四个方法)
step1:new一个TimerTask的子类,重写run方法来指定具体的任务
package com.zang.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimerTask; public class MyTimerTask extends TimerTask{ private String name; //构造器 public MyTimerTask(String inputName){ name = inputName; } //重写run方法,打印当前时间。 @Override public void run() { Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //打印当前文件的内容 System.out.println("Current exec name is " + sdf.format(calendar.getTime())); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
step2:new一个Timer类,Timer的构造函数里会起一个单独的线程来执行计划任务。
package com.zang.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Timer; public class MyTimer { public static void main(String[] args) { //1.创建一个Timer实例 Timer timer = new Timer(); //2.创建一个MyTimerTask实例 MyTimerTask myTimerTask = new MyTimerTask("My First Timer..."); //日期格式化和输出当前时间 Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("current time is " + sdf.format(calendar.getTime())); //3.通过timer定时定频率调用MyTimerTask的业务逻辑 //两秒之后第一次执行,之后每隔一秒执行一次 timer.schedule(myTimerTask, 2000L, 1000L); } }
jdk中的代码实现如下:
public Timer() { this("Timer-" + serialNumber()); } public Timer(String name) { thread.setName(name); thread.start(); }
输出如下:
2.2 Timer其他函数(此处不作详解)
TimerTask的cancel()函数的作用:取消当前TimerTask里的任务。
TimerTask的scheduleExecutionTime()作用:返回此任务最近实际执行的已安排执行的时间,返回值:最近发生此任务执行安排的时间,为long型。
Timer对象的cancel()函数的作用:终止此计时器,丢弃所有当前已安排的任务。
Timer的purge()函数的作用:从此计时器的任务队列中移除所有已取消的任务。返回值:从队列中移除的任务数。
2.3 schedule 和 scheduleAtFixedRate的区别
这两个方法都是任务调度方法,他们之间区别是,schedule会保证任务的间隔是按照定义的period参数严格执行的,如果某一次调度时间比较长,那么后面的时间会顺延,保证调度间隔都是period,而scheduleAtFixedRate是严格按照调度时间来的,如果某次调度时间太长了,那么会通过缩短间隔的方式保证下一次调度在预定时间执行。举个栗子:你每个3秒调度一次,那么正常就是0,3,6,9s这样的时间,如果第二次调度花了2s的时间,如果是schedule,就会变成0,3+2,8,11这样的时间,保证间隔,而scheduleAtFixedRate就会变成0,3+2,6,9,压缩间隔,保证调度时间。即schedule的执行基于上一次的完成时间, scheduleAtFixedRate的执行基于上一次的开始时间。
3. 综合使用demo
利用Timer控制两个机器人——灌水机器人负责灌水,水满即停止工作;跳舞机器人不负责灌水,水满之后跳舞两秒,停止工作。
创建两个TimerTask的子类,重写run方法来指定具体的任务。
package com.zang.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimerTask; public class DancingRobot extends TimerTask{ @Override public void run() { //获取最近一次任务执行时间,并将其格式化 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Schedule exec name is " + sdf.format(scheduledExecutionTime())); System.out.println("I am dacing.... "); } }
package com.zang.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; import java.util.TimerTask; public class WaterRobot extends TimerTask { private Timer timer; //水桶的容量,最大容量为5L private Integer bucketCapacity = 0; public WaterRobot(Timer inputTimer) { timer = inputTimer; } @Override public void run() { //注水直到水满为止 if(bucketCapacity < 5){ System.out.println("Add 1L water into the bucket."); bucketCapacity++; }else{ //水满之后停止 System.out.println("The number of canceled task in timer is(BEFORE) " + timer.purge()); cancel(); System.out.println("The bucket is fulling and the waterRobot has been aborted."); System.out.println("Current water is "+ bucketCapacity +"L"); //输出被取消的任务数 System.out.println("The number of canceled task in timer is(AFTER) " + timer.purge()); //等待两秒,终止timer里的所有内容 try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } timer.cancel(); } } }
Timer对象执行任务
package com.zang.timer; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class RobotExecutor { public static void main(String[] args) { Timer timer = new Timer(); //获取当前时间 Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current time is " + sdf.format(calendar.getTime())); DancingRobot dr = new DancingRobot(); WaterRobot wr = new WaterRobot(timer); /* * 灌水机器人负责灌水,水满即停止工作 * 跳舞机器人不负责灌水,水满之后跳舞两秒,停止工作 */ timer.schedule(dr, calendar.getTime(), 2000); timer.schedule(wr, calendar.getTime(), 1000); } }
控制台输出:
以上是关于Timer使用的主要内容,如果未能解决你的问题,请参考以下文章
JAVA随笔篇一(Timer源代码分析和scheduleAtFixedRate的使用)
Erlang timer:sleep(1000) 导致线程死机