java.util.Timer计时器有管理任务延迟执行("如1000ms后执行任务")以及周期性执行("如每500ms执行一次该任务")。java
可是,Timer存在一些缺陷:ide
1,Timer对调度的支持是基于绝对时间,而不是相对时间的,由此任务对系统时钟的改变是敏感的;ScheduledThreadExecutor只支持相对时间。 oop
2,若是TimerTask抛出未检查的异常,Timer将会产生没法预料的行为。Timer线程并不捕获异常,因此 TimerTask抛出的未检查的异常会终止timer线程。此时,已经被安排但还没有执行的TimerTask永远不会再执行了,新的任务也不能被调度了。 测试
测试代码:spa
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呢?日志
测试代码以下:code
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
程序能正确的输出。it