Java定时调度任务详解之Timer篇
2017-09-30 01:23
513 查看
简单介绍
什么是定时任务调度
基于给定的时间点,给定的时间间隔,或者给定的执行次数自动执行的任务。Java中定时调度工具
Timer ---〉 jdkQuartz --〉 第三方jar包,实现更完善。
尽量使用jdk提供的timer
Timer简介
有且仅有一个后台线程对多个业务线程进行定时定频率的调度。主要构件
Timer 可以理解为每个后台执行的线程,TimerTask业务线程
Timer工具类详解
第一个简单实例
import java.util.TimerTask; public class MyTaskTimer extends TimerTask { private String name; public MyTaskTimer(String name) { this.name = name; } @Override public void run() { System.out.println("Current name is: " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }测试类
import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1"); //3、通过timer定时定频率调用myTimerTask的业务逻辑 // 即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次 timer.schedule(myTaskTimer, 2000L, 1000L); } }
Timer的定时调度函数
schedule(task, time)
task --> 所要安排的任务在时间等于或超过time的时候执行且仅执行一次task
实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimerTask; public class MyTaskTimer extends TimerTask { private String name; public MyTaskTimer(String name) { this.name = name; } @Override public void run() { Calendar calendar = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("current exect time:" + sf.format(calendar.getTime())); System.out.println("Current name is: " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
测试类
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1"); /** * 获取当前时间,并设置成距离当前时间三秒之后的时间 */ 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);//设置三秒之后的时间 myTaskTimer.setName("schedule1"); timer.schedule(myTaskTimer, calendar.getTime()); } }
schedule(task, time, period)
task --> 所要安排的任务time -->首次执行任务的时间
period -->执行一次task的时间间隔,单位是毫秒
时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
测试类
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1"); /** * 获取当前时间,并设置成距离当前时间三秒之后的时间 */ 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);//设置三秒之后的时间 myTaskTimer.setName("schedule2"); timer.schedule(myTaskTimer, calendar.getTime(), 2000);//执行3秒钟之后的时间 } }
schedule(task, delay)
task --> 所要安排的任务delay --> 执行任务前的延时时间,单位毫秒
等待delay毫秒后执行且仅执行一次task
实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1"); /** * 获取当前时间,并设置成距离当前时间三秒之后的时间 */ 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);//设置三秒之后的时间 myTaskTimer.setName("schedule3"); timer.schedule(myTaskTimer, 2000);//执行3秒钟之后的时间 } }
schedule(task, delay, period)
task --> 所要安排的任务delay --> 执行任务前的延时时间,单位毫秒
period -->执行一次task的时间间隔,单位是毫秒
等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");
/** * 获取当前时间,并设置成距离当前时间三秒之后的时间 */ myTaskTimer.setName("schedule4"); 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);//设置三秒之后的时间myTaskTimer.setName("schedule4");timer.schedule(myTaskTimer, 2000, 2000);//执行3秒钟之后的时间}}
scheduleAtFixedRate的两种用法
scheduleAtFixedRate(task, time, period)
task --> 所要安排的任务time -->首次执行任务的时间
period -->执行一次task的时间间隔,单位是毫秒
时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
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);//设置三秒之后的时间
myTaskTimer.setName("scheduleAtFixedRate1");
timer.scheduleAtFixedRate(myTaskTimer, calendar.getTime(), 2000);//执行3秒钟之后的时间
}
}
scheduleAtFixedRate(task, delay, period)
task --> 所要安排的任务delay --> 执行任务前的延时时间,单位毫秒
period -->执行一次task的时间间隔,单位是毫秒
等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
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);//设置三秒之后的时间
myTaskTimer.setName("scheduleAtFixedRate2");
timer.scheduleAtFixedRate(myTaskTimer, 3000, 2000);//距离当前时间3秒钟
}
}
其它重要函数
cancel()
取消当前TimerTask里的任务实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimerTask; public class MyTaskTimer extends TimerTask { private String name; private Integer count = 0; public MyTaskTimer(String name) { this.name = name; } @Override public void run() { if (count < 3) { Calendar calendar = Calendar.getInstance(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("current exect time:" + sf.format(calendar.getTime())); System.out.println("Current name is: " + name); count ++; } else { cancel(); System.out.println("Task Cancle"); } } public String getName() { return name; } public void setName(String name) { this.name = name; } }
测试类
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
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);//设置三秒之后的时间
myTaskTimer.setName("schedule");
timer.schedule(myTaskTimer, 3000, 2000);//距离当前时间3秒钟
}
}
scheduleExecutionTime()
返回此任务最近实际执行的已安排执行的时间,返回值为最近发生此任务执行安排的时间,为long型实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class MyTimer { public static void main(String[] args) { // 1、创建一个Timer实例 Timer timer = new Timer(); //2、创建一个MyTimerTask实例 MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
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);//设置三秒之后的时间
myTaskTimer.setName("schedule");
timer.schedule(myTaskTimer, 3000);//距离当前时间3秒钟,只执行一次
System.out.println("schedule time is :" + sf.format(myTaskTimer.scheduledExecutionTime()));
}
}
Timer下的cancel()
终止此计时器,丢弃所有当前已安排的任务实例:
import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; public class CancleTest { public static void main(String[] args) throws InterruptedException { //创建一个Timer实例 Timer timer = new Timer(); //创建TaskTimer实例 MyTaskTimer task1 = new MyTaskTimer("task1"); MyTaskTimer task2 = new MyTaskTimer("task2"); //获取当前时间并打印 Date startDate = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("start time is :" + sf.format(startDate)); timer.schedule(task1, 3000L, 2000L); timer.schedule(task2, 1000L, 2000L); //休眠5秒 Thread.sleep(5000L); //获取当前时间并打印 Date cancelTime = new Date(); System.out.println("cancel time is :" + sf.format(cancelTime)); //取消所有任务 timer.cancel(); System.out.println("Tasks all canceled"); } }
Timer下的purge()
从此计时器的任务队列中移除所有已取消的任务,返回值 从队列中移除的任务数实例
import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; public class CancleTest { public static void main(String[] args) throws InterruptedException { //创建一个Timer实例 Timer timer = new Timer(); //创建TaskTimer实例 MyTaskTimer task1 = new MyTaskTimer("task1"); MyTaskTimer task2 = new MyTaskTimer("task2"); //获取当前时间并打印 Date startDate = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("start time is :" + sf.format(startDate)); timer.schedule(task1, 3000L, 2000L); timer.schedule(task2, 1000L, 2000L); System.out.println("current canceled task number is:" + timer.purge()); //休眠2秒 Thread.sleep(2000L); //获取当前时间并打印 Date cancelTime = new Date(); System.out.println("cancel time is :" + sf.format(cancelTime)); //取消task2的任务 task2.cancel(); System.out.println("current canceled task number is:" + timer.purge()); } }
schedule和scheduleAtFixRate区别
schedule方法
“fixed-delay” ;如果第一次执行时间被delay,随后的执行时间按照上一次实际完成的时间点进行计算.实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; import java.util.TimerTask; public class DifferenceTest { public static void main(String[] args) { final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar calendar = Calendar.getInstance(); System.out.println("current time is : " + sf.format(calendar.getTime())); //设置成6秒的时间,若当前时间为2017-11-11 00:00:06 //那么设置之后的时间变成2017-11-11 00:00:00 calendar.add(Calendar.SECOND, -6); Timer timer = new Timer(); //第一次执行时间为6秒前,之后每隔两秒钟执行一次 timer.schedule(new TimerTask() { @Override public void run() { //打印当前计划执行时间 System.out.println("schedule exect time is:" + sf.format(scheduledExecutionTime())); System.out.println("Task is being exected"); } },calendar.getTime(), 2000L); } }
scheduleAtFixRate方法
“fixed-rate” ;如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,并且为了赶上进度会多次执行任务,因此TimerTask中的执行体需要考虑同步任务执行时间超出执行时间间隔
schedule方法下一次执行时间相对于上一次实际执行完成的是时间点,因此执行时间会不断延后。
实例
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; import java.util.TimerTask; public class DifferenceTest { public static void main(String[] args) { final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar calendar = Calendar.getInstance(); System.out.println("current time is : " + sf.format(calendar.getTime())); Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } //打印当前计划执行时间 System.out.println("schedule exect time is:" + sf.format(scheduledExecutionTime())); System.out.println("Task is being exected"); } },calendar.getTime(), 2000L); } }scheduleAtFixRate方法
下一次执行时间相对于上一次开始的时间点,因此执行时间不会延后,因此存在并发性。
实际应用
import java.text.SimpleDateFormat; import java.util.TimerTask; /** * 跳舞机器人,每隔两秒钟跳舞 */ public class DancingRobot extends TimerTask { @Override public void run() { SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Scheduled exec time is : " + sf.format(scheduledExecutionTime())); System.out.println("Dancing happily"); } }
import java.util.Timer; import java.util.TimerTask; /** * 灌水机器人,水注入满5升后,等待两秒钟后,取消所有 * @author lijingyu * */ public class WaterRobot extends TimerTask { private Timer timer; 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 :" + timer.purge()); //水满后停止 cancel(); System.out.println("The WaterRobot has bean aborted!"); System.out.println("The number of canceled task in timer is :" + timer.purge()); System.out.println("Current water is " + bucketCapacity + "L"); try { Thread.sleep(2000L); } catch (InterruptedException e) { e.printStackTrace(); } timer.cancel();//取消所有 } } }执行机器人
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Timer; public class ExectorRobot { 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("Current time is" + sf.format(calendar.getTime())); DancingRobot dr = new DancingRobot(); WaterRobot wr = new WaterRobot(timer); timer.schedule(dr, calendar.getTime(), 2000L); timer.scheduleAtFixedRate(wr, calendar.getTime(), 1000L); } }
Timer缺陷
管理并发任务的缺陷
Timer有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符。当任务抛出异常时缺陷
如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行。Timer的使用禁区
对时效性要求较高的多任务并发作业;对复杂的任务调度。参考
慕课网相关文章推荐
- Java定时任务调度工具详解之Timer篇
- Java定时任务调度工具详解(1)— Timer 简介
- Java定时任务调度工具详解(4)— Quartz 之 Job/JobDetail/JobExecutionContext/JobDataMap
- Java定时任务调度工具详解(2)— Timer 函数的综合应用
- Java定时任务调度工具详解之Quartz篇(中级)一:浅谈JobExecutionContext&JobDatai&浅谈Trigger
- Java定时任务调度工具详解之Quartz篇
- Java定时任务调度工具详解之Quartz篇(中级)二:SimpleTrigger& CronTrigger&浅谈Scheduler&QuartzProperties文件
- Java定时任务调度工具详解(3)— Quartz 简介
- Java定时任务调度工具详解之Timer篇(初级)Timer函数的综合应用
- Java定时任务调度工具详解(5)— Quartz 之 Trigger
- Java定时任务调度工具详解之Timer
- Java定时任务调度工具详解(8)— Quartz 之 quartz.properties文件
- Java定时任务调度工具详解之Timer篇(初级)
- Java定时任务调度工具详解(6)— Quartz 之 SimpleTrigger、CronTrigger、Cron表达式
- Java定时任务调度工具详解之Quartz
- Java定时任务调度工具详解(7)— Quartz 之 Scheduler
- Java定时任务调度工具详解之Timer篇
- [译]Java定时任务调度-Quartz文档(五)SimpleTrigger
- java定时任务调度工具Timer和Quartz
- 详解java定时任务