JDK库中Timer类主要负责设计任务的功能,也就是指定任务在某一时间点执行。封装任务的类是TimerTask类。
验证Timer对象的schedule(TimerTask task,Date date)方法
工程代码如下
package Timer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Test {
private static Timer timer = new Timer();
static public class MyTask extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("task do at "+new Date());
}
}
public static void main(String[] args) throws ParseException {
MyTask myTask = new MyTask();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dataString = "2018-05-18 15:10:03";
Date parse = dateFormat.parse(dataString);
System.out.println("running time is "+new Date());
timer.schedule(myTask, parse);
}
}
运行结果
running time is Fri May 18 15:09:28 CST 2018
task do at Fri May 18 15:10:03 CST 2018
当任务设置时间在当前时间之后的。会在该设置时间被执行。若设置时间已经过去,任务会被立即执行。
多个TimerTask任务及延时测试
TimerTask是以队列的形式一个个被顺序执行的,所以执行的时间会和预期时间不一致。如下工程,设置两个任务间隔5秒被执行,因为先执行的任务处理的时间为20秒才结束,所以任务2顺延20秒才执行。
package Timer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Test {
private static Timer timer = new Timer();
private static Timer timer2 = new Timer();
static public class MyTask1 extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("task do at "+new Date());
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
static public class MyTask2 extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("task do at "+new Date());
}
}
public static void main(String[] args) throws ParseException {
MyTask1 myTask1 = new MyTask1();
MyTask2 myTask2 = new MyTask2();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dataString = "2018-05-18 15:04:00";
String dataString2 = "2018-05-18 15:04:05";
Date parse = dateFormat.parse(dataString);
Date parse2 = dateFormat.parse(dataString2);
System.out.println("running time is "+new Date());
timer.schedule(myTask1, parse);
timer.schedule(myTask2, parse);
}
}
结果如下
running time is Fri May 18 15:02:53 CST 2018
task do at Fri May 18 15:04:00 CST 2018
task do at Fri May 18 15:04:20 CST 2018
验证Timer对象的schedule(TimerTask task, Date firsttime ,long period)方法
使任务在指定时间后,按指定周期执行。
工程代码如下
package Timer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Test {
private static Timer timer = new Timer();
static public class MyTask extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("task do at "+new Date());
}
}
public static void main(String[] args) throws ParseException {
MyTask myTask = new MyTask();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dataString = "2018-05-18 15:17:03";
Date parse = dateFormat.parse(dataString);
System.out.println("running time is "+new Date());
timer.schedule(myTask, parse, 4000);
}
}
运行结果
running time is Fri May 18 15:17:13 CST 2018
task do at Fri May 18 15:17:13 CST 2018
task do at Fri May 18 15:17:17 CST 2018
task do at Fri May 18 15:17:21 CST 2018
task do at Fri May 18 15:17:25 CST 2018
task do at Fri May 18 15:17:29 CST 2018
task do at Fri May 18 15:17:33 CST 2018
程序会在设置的firsttime 时间点第一次执行(firsttime 对于当前时间处于未来),以period毫秒的时间为周期循环执行。
如果出现周期为4秒而任务运行时间大于4秒,所有任务都会被延时,运行间隔为大的那个时间间隔。
TimeTask类的cancle()方法
TimeTask类的cancle()方法的作用是将自身从任务队列中清除。
Timer类的cancle()方法
Timer类的cancle()方法是将队列中的所有任务清除。
验证Timer对象的schedule(TimerTask task, long delay)方法
以当前时间为基准,向后延时delay毫秒单位的时间才运行该任务。
工程代码如下
package Timer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Test {
private static Timer timer = new Timer();
static public class MyTask extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("task1 do at "+new Date());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
static public class MyTask2 extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("task2 do at "+new Date());
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) throws ParseException {
MyTask myTask = new MyTask();
MyTask2 myTask2 = new MyTask2();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dataString = "2018-05-18 15:35:53";
String dataString2 = "2018-05-18 15:35:53";
Date parse = dateFormat.parse(dataString);
Date parse2 = dateFormat.parse(dataString2);
System.out.println("running time is "+new Date());
timer.schedule(myTask,6000);
timer.schedule(myTask2, 2000);
}
}
运行结果
running time is Fri May 18 15:39:33 CST 2018
task2 do at Fri May 18 15:39:35 CST 2018
task1 do at Fri May 18 15:39:43 CST 2018
延时情况仍存在
验证Timer对象的schedule(TimerTask task, long delay, long period)方法
在当前时间基准上,延时delay毫秒之后,以period为周期循环执行。
验证Timer对象的scheduleAtFixedRate(task, firstTime, period)方法
- scheduleAtFixedRate方法和schedule方法都是按顺序执行的,所以都是线程安全的。
- 两者的区别在于:在不延时的情况下,scheduleAtFixedRate是根据任务运行结束的时间来计算下一次任务运行的时间的。schedule是根据任务运行开始的时间来计算下次任务运行的时间的
- 而在延时的情况下,两种方法都是根据任务运行结束的时间来计算下一次任务开始的时间的