Java定时任务调度工具详解之Timer篇
1.什么是定时任务调度
基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务
2. Timer和Quartz的区别
2.1 出生不同 (Timer由jdk直接提供,Quartz源于OpenSymphony)
2.2 能力区别 (主要体现在对时间的控制上)
2.3 底层机制 (Timer只有一个后台线程执行定时任务,Quartz则拥有后台执行线程池)
3.Timer的定义
有且仅有一个后台线程对多个业务线程进行定时定频率的调度
4.主要构件(如果)
5.Timer工具类详解(如图)
6.案例一:第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
//打印当前name的内容
System.out.println("Current name: "+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyTimer.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimer {
public static void main(String[] args) {
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
timer.schedule(myTimerTask,2000L,1000L);
}
}
执行结果:
7. Timer的定时调度函数
7.1 schedule的四种用法
7.1.1 schedule(task,time)
参数:
task ---- 所要安排的任务
time ---- 执行任务的时间
作用: 在时间等于或超过time的时候执行且仅执行一次task
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyTimer.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimer {
public static void main(String[] args) {
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask,2000L,1000L);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date time = calendar.getTime();
System.out.println("Current time is :"+simpleDateFormat.format(time));
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
calendar.add(Calendar.SECOND,3);
myTimerTask.setName("schedule1");
timer.schedule(myTimerTask,calendar.getTime());
}
}
执行结果:
7.1.2 schedule(task,time,period)
参数:
task ---- 所要安排的任务
time ---- 首次执行任务的时间
period ---- 执行一次task的时间间隔,单位是毫秒
作用: 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyTimer.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimer {
public static void main(String[] args) {
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask,2000L,1000L);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date time = calendar.getTime();
System.out.println("Current time is :"+simpleDateFormat.format(time));
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
calendar.add(Calendar.SECOND,3);
//1.在时间等于或超过time的时候执行且执行一次task并打印任务的名字
//myTimerTask.setName("schedule1");
//timer.schedule(myTimerTask,calendar.getTime());
//2.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
myTimerTask.setName("schedule2");
timer.schedule(myTimerTask,calendar.getTime(),2000);
}
}
执行结果:
7.1.3 schedule(task,delay)
参数:
task ---- 所要安排的任务
delay ---- 执行任务前的延迟时间,单位是毫秒
作用: 等待delay毫秒后执行且仅执行一次task
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimerTask; /** * Created by gailun on 2018/1/5. */ public class MyTimerTask extends TimerTask{ private String name; public MyTimerTask(String name) { this.name = name; } @Override public void run() { //打印当前执行时间 Calendar calendar = Calendar.getInstance(); Date time = calendar.getTime(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Run Current time is :"+simpleDateFormat.format(time)); //打印当前name的内容 System.out.println("Current name: "+name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
MyTimer.java代码(如下)
import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Timer; /** * Created by gailun on 2018/1/5. */ public class MyTimer { public static void main(String[] args) { //1.创建一个Timer实例 Timer timer = new Timer(); //2.创建一个MyTimerTask实例 MyTimerTask myTimerTask = new MyTimerTask("No.1"); //3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次 //timer.schedule(myTimerTask,2000L,1000L); Calendar calendar = Calendar.getInstance(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date time = calendar.getTime(); System.out.println("Current time is :"+simpleDateFormat.format(time)); /** * 获取当前时间,并设置成距离当前时间三秒之后的时间 */ calendar.add(Calendar.SECOND,3); //1.在时间等于或超过time的时候执行且执行一次task并打印任务的名字 //myTimerTask.setName("schedule1"); //timer.schedule(myTimerTask,calendar.getTime()); //2.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task //myTimerTask.setName("schedule2"); //timer.schedule(myTimerTask,calendar.getTime(),2000); //3.等待delay毫秒后执行且执行一次task myTimerTask.setName("schedule3"); timer.schedule(myTimerTask,2000); } }执行结果:
7.1.4 schedule(task,delay,period)
参数:
task ---- 所要安排的任务
delay ---- 执行任务前的延迟时间,单位是毫秒
period ---- 执行一次task的时间间隔,单位是毫秒
作用: 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyTimer.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimer {
public static void main(String[] args) {
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask,2000L,1000L);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date time = calendar.getTime();
System.out.println("Current time is :"+simpleDateFormat.format(time));
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
calendar.add(Calendar.SECOND,3);
//1.在时间等于或超过time的时候执行且执行一次task并打印任务的名字
//myTimerTask.setName("schedule1");
//timer.schedule(myTimerTask,calendar.getTime());
//2.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("schedule2");
//timer.schedule(myTimerTask,calendar.getTime(),2000);
//3.等待delay毫秒后执行且执行一次task
//myTimerTask.setName("schedule3");
//timer.schedule(myTimerTask,2000);
//4.等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
myTimerTask.setName("schedule4");
timer.schedule(myTimerTask,3000,2000);
}
}
执行结果:
7.2 scheduleAtFixedRate的两种用法
7.2.1 scheduleAtFixedRate(task,time,period)
参数:
task ---- 所要安排的任务
time ---- 首次执行任务的时间
period ---- 执行一次task的时间间隔,单位是毫秒
作用: 时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyTimer.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimer {
public static void main(String[] args) {
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask,2000L,1000L);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date time = calendar.getTime();
System.out.println("Current time is :"+simpleDateFormat.format(time));
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
calendar.add(Calendar.SECOND,3);
//1.在时间等于或超过time的时候执行且执行一次task并打印任务的名字
//myTimerTask.setName("schedule1");
//timer.schedule(myTimerTask,calendar.getTime());
//2.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("schedule2");
//timer.schedule(myTimerTask,calendar.getTime(),2000);
//3.等待delay毫秒后执行且执行一次task
//myTimerTask.setName("schedule3");
//timer.schedule(myTimerTask,2000);
//4.等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("schedule4");
//timer.schedule(myTimerTask,3000,2000);
//5.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次
myTimerTask.setName("scheduleAtFixedRate1");
timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000);
}
}
执行结果:
7.2.2 scheduleAtFixedRate(task,delay,period)
参数:
task ---- 所要安排的任务
delay ---- 执行任务前的延迟时间,单位是毫秒
period ---- 执行一次task的时间间隔,单位是毫秒
作用: 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyTimer.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimer {
public static void main(String[] args) {
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask,2000L,1000L);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date time = calendar.getTime();
System.out.println("Current time is :"+simpleDateFormat.format(time));
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
calendar.add(Calendar.SECOND,3);
//1.在时间等于或超过time的时候执行且执行一次task并打印任务的名字
//myTimerTask.setName("schedule1");
//timer.schedule(myTimerTask,calendar.getTime());
//2.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("schedule2");
//timer.schedule(myTimerTask,calendar.getTime(),2000);
//3.等待delay毫秒后执行且执行一次task
//myTimerTask.setName("schedule3");
//timer.schedule(myTimerTask,2000);
//4.等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("schedule4");
//timer.schedule(myTimerTask,3000,2000);
//5.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次
//myTimerTask.setName("scheduleAtFixedRate1");
//timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000);
//6. 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
myTimerTask.setName("scheduleAtFixedRate2");
timer.scheduleAtFixedRate(myTimerTask,3000,2000);
}
}
执行结果:
8.TimerTask的两个重要函数
8.1 cancel()
作用: 取消当前TimerTask里的任务
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
private Integer count =0;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
if (count< 3){
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
count++;
}else {
cancel();
System.out.println("Cancel task");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
}
MyTimer.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimer {
public static void main(String[] args) {
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask,2000L,1000L);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date time = calendar.getTime();
System.out.println("Current time is :"+simpleDateFormat.format(time));
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
calendar.add(Calendar.SECOND,3);
//1.在时间等于或超过time的时候执行且执行一次task并打印任务的名字
//myTimerTask.setName("schedule1");
//timer.schedule(myTimerTask,calendar.getTime());
//2.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("schedule2");
//timer.schedule(myTimerTask,calendar.getTime(),2000);
//3.等待delay毫秒后执行且执行一次task
//myTimerTask.setName("schedule3");
//timer.schedule(myTimerTask,2000);
//4.等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("schedule4");
//timer.schedule(myTimerTask,3000,2000);
//5.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次
//myTimerTask.setName("scheduleAtFixedRate1");
//timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000);
//6. 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
myTimerTask.setName("scheduleAtFixedRate2");
timer.scheduleAtFixedRate(myTimerTask,3000,2000);
}
}
执行结果:
8.2 scheduledExecutionTime()
作用:返回此任务最近实际执行的已安排执行的时间
返回值:最近发生此任务执行安排的时间,为long型
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
private Integer count =0;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
if (count< 3){
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
count++;
}else {
cancel();
System.out.println("Cancel task");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {return count;}
public void setCount(Integer count) {
this.count = count;
}
}
MyTimer.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimer {
public static void main(String[] args) {
//1.创建一个Timer实例
Timer timer = new Timer();
//2.创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("No.1");
//3.通过Timer定时定频率调用myTimerTask的业务逻辑,即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask,2000L,1000L);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date time = calendar.getTime();
System.out.println("Current time is :"+simpleDateFormat.format(time));
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
*/
calendar.add(Calendar.SECOND,3);
//1.在时间等于或超过time的时候执行且执行一次task并打印任务的名字
//myTimerTask.setName("schedule1");
//timer.schedule(myTimerTask,calendar.getTime());
//2.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("schedule2");
//timer.schedule(myTimerTask,calendar.getTime(),2000);
//3.等待delay毫秒后执行且执行一次task
//myTimerTask.setName("schedule3");
//timer.schedule(myTimerTask,2000);
//4.等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
myTimerTask.setName("schedule4");
timer.schedule(myTimerTask,3000);
System.out.println("schedule time is"+simpleDateFormat.format(myTimerTask.scheduledExecutionTime()));
//5.时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次
//myTimerTask.setName("scheduleAtFixedRate1");
//timer.scheduleAtFixedRate(myTimerTask,calendar.getTime(),2000);
//6. 等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
//myTimerTask.setName("scheduleAtFixedRate2");
//timer.scheduleAtFixedRate(myTimerTask,3000,2000);
}
}
执行结果:
9. Timer的其他函数
9.1 cancel()
作用: 终止此计时器,丢弃所有当前已安排的任务
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
private Integer count =0;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
if (count< 3){
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
count++;
}else {
cancel();
System.out.println("Cancel task");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {return count;}
public void setCount(Integer count) {
this.count = count;
}
}
CancelTest.java代码(如下)
import com.mysql.fabric.xmlrpc.base.Data;
import javafx.scene.input.DataFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/6.
*/
public class CancelTest {
public static void main(String[] args) throws InterruptedException {
//创建Timer实例
Timer timer = new Timer();
//创建TimerTask实例
MyTimerTask task1 = new MyTimerTask("task1");
MyTimerTask task2 = new MyTimerTask("task2");
//获取当前的执行时间并打印
Data startTime = new Data();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("startTime is"+simpleDateFormat.format(startTime));
//task1首次执行是距离现在时间3秒后执行,之后每隔2秒执行一次
//task2首次执行时距离现在时间1秒后执行,之后每隔2秒执行一次
timer.schedule(task1,3000,2000);
timer.schedule(task2,1000,2000);
//休眠5秒
Thread.sleep(5000);
//获取当前的执行时间并打印
Date cancelTime = new Date();
System.out.println("cancelTime is"+simpleDateFormat.format(cancelTime));
//取消所有任务
timer.cancel();
System.out.println("Task all cancel !");
}
}
执行结果:
9.2 purge()
作用: 从此计时器的任务队列中移除所有已取消的任务
返回值: 从队列中移除的任务数\
MyTimerTask.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/5.
*/
public class MyTimerTask extends TimerTask{
private String name;
private Integer count =0;
public MyTimerTask(String name) {
this.name = name;
}
@Override
public void run() {
if (count< 3){
//打印当前执行时间
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Run Current time is :"+simpleDateFormat.format(time));
//打印当前name的内容
System.out.println("Current name: "+name);
count++;
}else {
cancel();
System.out.println("Cancel task");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {return count;}
public void setCount(Integer count) {
this.count = count;
}
}
CancelTest.java代码(如下)
import javafx.scene.input.DataFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
/**
* Created by gailun on 2018/1/6.
*/
public class CancelTest {
public static void main(String[] args) throws InterruptedException {
//创建Timer实例
Timer timer = new Timer();
//创建TimerTask实例
MyTimerTask task1 = new MyTimerTask("task1");
MyTimerTask task2 = new MyTimerTask("task2");
//获取当前的执行时间并打印
Date startTime = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("startTime is"+simpleDateFormat.format(startTime));
//task1首次执行是距离现在时间3秒后执行,之后每隔2秒执行一次
//task2首次执行时距离现在时间1秒后执行,之后每隔2秒执行一次
timer.schedule(task1,3000,2000);
timer.schedule(task2,1000,2000);
System.out.println("current purge number is : "+timer.purge());
//休眠2秒
Thread.sleep(2000);
//获取当前的执行时间并打印
Date cancelTime = new Date();
System.out.println("cancelTime is"+simpleDateFormat.format(cancelTime));
//取消所有任务
task2.cancel();
System.out.println("current canceled task purge number is : "+timer.purge());
}
}
执行结果:
10. schedule与scheduleAtFixedRate的区别
10.1两种情况看区别:
1.首次计划执行的时间早于当前的时间
1.1 schedule方法: "fixed-delay";如果第一次执行时间被delay了,随后的执行时间按照上一次实际执行完成的时间点进行计算
DifferenceTest.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/6.
*/
public class DifferenceTest {
public static void main(String[] args) {
//规定时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取当前的具体时间
Calendar calendar = Calendar.getInstance();
System.out.println("current time is :"+simpleDateFormat.format(calendar.getTime()));
//设置成6秒前的时间
calendar.add(Calendar.SECOND,-6);
Timer timer = new Timer();
//第一次执行时间为6秒前,之后每隔两秒钟执行一次
timer.schedule(new TimerTask() {
@Override
public void run() {
//打印当前的计划执行时间
System.out.println("scheduled exec time is : "+simpleDateFormat.format(scheduledExecutionTime()));
System.out.println("task is beging executed !");
}
},calendar.getTime(),2000);
}
}
执行结果:
1.2 scheduleAtFixedRate方法: "fixed-rate";如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,并且为了赶上进度会多次执行任务,因此TimerTask中的执行体需要考虑同步
DifferenceTest.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/6.
*/
public class DifferenceTest {
public static void main(String[] args) {
//规定时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取当前的具体时间
Calendar calendar = Calendar.getInstance();
System.out.println("current time is :"+simpleDateFormat.format(calendar.getTime()));
//设置成6秒前的时间
calendar.add(Calendar.SECOND,-6);
Timer timer = new Timer();
//第一次执行时间为6秒前,之后每隔两秒钟执行一次
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//打印当前的计划执行时间
System.out.println("scheduled exec time is : "+simpleDateFormat.format(scheduledExecutionTime()));
System.out.println("task is beging executed !");
}
},calendar.getTime(),2000);
}
}
执行结果:
2.任务执行所需时间超出任务的执行周期间隔
2.1 schedule方法:下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后
DifferenceTest1.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/6.
*/
public class DifferenceTest1 {
public static void main(String[] args) {
//规定时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取当前的具体时间
Calendar calendar = Calendar.getInstance();
System.out.println("current time is :"+simpleDateFormat.format(calendar.getTime()));
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//打印最近一次的计划执行时间
System.out.println("scheduled exec time is : "+simpleDateFormat.format(scheduledExecutionTime()));
System.out.println("task executes !");
}
},calendar.getTime(),2000);
}
}
执行结果:
2.2 scheduleAtFixedRate方法:下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性.
DifferenceTest1.java代码(如下)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/6.
*/
public class DifferenceTest1 {
public static void main(String[] args) {
//规定时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取当前的具体时间
Calendar calendar = Calendar.getInstance();
System.out.println("current time is :"+simpleDateFormat.format(calendar.getTime()));
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//打印最近一次的计划执行时间
System.out.println("scheduled exec time is : "+simpleDateFormat.format(scheduledExecutionTime()));
System.out.println("task executes !");
}
},calendar.getTime(),2000);
}
}
执行结果:
11. Timer函数的综合使用
案例:当水容量不足5L时,灌水机器人每隔2秒灌一次水且每次灌水为1L,同时跳舞机器人每隔一秒跳一次舞.当水容量为5L时灌水机器人不用工作了,并且两秒后跳舞机器人也不用工作了.
DancingRobot.java
import java.text.SimpleDateFormat;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/7.
*/
public class DancingRobot extends TimerTask {
@Override
public void run() {
//获取最近的一次任务执行的时间,并将其格式化
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("scheduled exec time is :"+simpleDateFormat.format(scheduledExecutionTime()));
System.out.println("Dancing Happily !");
}
}
WaterRobot.java
import java.sql.Time;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by gailun on 2018/1/7.
*/
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("All 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 been aborted");
System.out.println("The number of canceled task in timer is :"+timer.purge());
System.out.println("Current water is "+ bucketCapacity+"L");
//等待两秒钟,终止timer里面的所有内容
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
timer.cancel();
}
}
}
Executor.java
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
/**
* Created by gailun on 2018/1/7.
*/
public class Executor {
public static void main(String[] args) {
Timer timer = new Timer();
//获取当前的时间
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("current time is :"+simpleDateFormat.format(calendar.getTime()));
DancingRobot dr = new DancingRobot();
WaterRobot wr = new WaterRobot(timer);
timer.schedule(dr,calendar.getTime(),2000);
timer.scheduleAtFixedRate(wr,calendar.getTime(),1000);
}
}
运行结果:
12. Timer的缺陷
12.1 天生的两种缺陷
1.管理并发任务的缺陷
Timer有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符
2.当任务抛出异常时的缺陷
如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行
12.2 Timer的使用禁区
1.对时效性要求较高的多任务并发作业
2.对复杂的任务的调度