java.util.Timer计时器有管理任务延迟执行("如1000ms后执行任务")以及周期性执行("如每500ms执行一次该任务")。
但是,Timer存在一些缺陷:
1,Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;ScheduledThreadExecutor只支持相对时间。
2,如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以 TimerTask抛出的未检查的异常会终止timer线程。此时,已经被安排但尚未执行的TimerTask永远不会再执行了,新的任务也不能被调度了。
测试代码:
public class ScheduledExecutorTest {
public static void main(String[] args) throws Exception {
final ScheduledExecutorTest test = new ScheduledExecutorTest();
// test.lanuchTimer();
// Thread.sleep(1000*5);//5秒钟之后添加新任务
// test.addOneTask();
test.lanuchTimer2();
Thread.sleep(1000 * 5);// 5秒钟之后添加一个新任务
test.addOneTask2();
}
private final Timer timer = new Timer();
// 启动计时器
public void lanuchTimer2() {
timer.schedule(new TimerTask() {
@Override
public void run() {
throw new RuntimeException();
}
}, 1000 * 3, 500);
}
// 向计时器添加一个任务
public void addOneTask2() {
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello world");
}
}, 1000 * 1, 1000 * 5);
}
// public static void main(String[] args) throws Exception {
// TimerTest test = new TimerTest();
// test.lanuchTimer();
// Thread.sleep(1000*5);//5秒钟之后添加一个新任务
// test.addOneTask();
// }
}
测试代码结果:
Exception in thread "Timer-0" java.lang.RuntimeException
at com.technology.test.ScheduledExecutorTest$3.run(ScheduledExecutorTest.java:78)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
Exception in thread "main" java.lang.IllegalStateException: Timer already cancelled.
at java.util.Timer.sched(Unknown Source)
at java.util.Timer.schedule(Unknown Source)
at com.technology.test.ScheduledExecutorTest.addOneTask2(ScheduledExecutorTest.java:85)
at com.technology.test.ScheduledExecutorTest.main(ScheduledExecutorTest.java:68)
那么如果使用ScheduledExecutorService呢?
测试代码如下:
public class ScheduledExecutorTest {
// 线程池能按时间计划来执行任务,允许用户设定计划执行任务的时间,int类型的参数是设定
// 线程池中线程的最小数目。当任务较多时,线程池可能会自动创建更多的工作线程来执行任务
public ScheduledExecutorService scheduExec = Executors
.newScheduledThreadPool(1);
// 启动计时器
public void lanuchTimer() {
final Runnable task = new Runnable() {
@Override
public void run() {
throw new RuntimeException();
}
};
scheduExec.scheduleWithFixedDelay(task, 1000 * 5, 1000 * 10,
TimeUnit.MILLISECONDS);
}
// 添加新任务
public void addOneTask() {
final Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("welcome to china");
}
};
scheduExec.scheduleWithFixedDelay(task, 1000 * 1, 1000,
TimeUnit.MILLISECONDS);
}
public static void main(String[] args) throws Exception {
final ScheduledExecutorTest test = new ScheduledExecutorTest();
// test.lanuchTimer();
// Thread.sleep(1000*5);//5秒钟之后添加新任务
// test.addOneTask();
test.lanuchTimer();
Thread.sleep(1000 * 5);// 5秒钟之后添加一个新任务
test.addOneTask();
}
}
输入日志信息为:
welcome to china
welcome to china
welcome to china
程序能正确的输出。