Timer类
-
传统的timer的缺点:Timer对任务的调度是基于绝对时间的;所有的TimerTask只有一个线程TimerThread来执行,因此同一时刻只有一个TimerTask在执行;
-
任何一个TimerTask的执行异常都会导致Timer终止所有任务;由于基于绝对时间并且是单线程执行,因此在多个任务调度时,长时间执行的任务被执行后有可能导致短时间任务快速在短时间内被执行多次或者干脆丢弃多个任务。
public static void main(String[] args) throws ParseException { Timer myTimer = new Timer(); myTimer.schedule(new Worker(), 1000);//1秒后执行 //2012-02-28 09:58:00执行 myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00")); myTimer.schedule(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次 //2012-02-28 09:58:00执行一次 以后每秒执行一次,如果设定的时间点在当前时间之前,任务会被马上执行,然后开始按照设定的周期定时执行任务 myTimer.schedule(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000); myTimer.scheduleAtFixedRate(new Worker(), 5000,1000);//5秒后执行 每一秒执行一次 如果该任务因为某些原因(例如垃圾收集)而延迟执行,那么接下来的任务会尽可能的快速执行,以赶上特定的时间点 myTimer.scheduleAtFixedRate(new Worker(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2012-02-28 09:58:00"),1000);//和上个类似 }
-
Timer执行周期任务时依赖系统时间,如果当前系统时间发生变化会出现一些执行上的变化,ScheduledExecutorService基于时间的延迟,不会由于系统时间的改变发生执行变化。
-
在多个Timer执行任务的时候,实际上是一个线程再执行任务,相当于第一个timerTask任务执行完了,然后计算事件再执行下一个任务,可以通过线程池的方法来将该超过两个人timer的timetask并发执行。
-
Timer当任务抛出异常时的缺陷,当Timer抛出异常时,该timer下的所有的timertask会全部停止执行,但相框只有一个任务。
-
其中schedule方法和scheduleAtFixedRate方法的侧重点不同,schedule方法侧重保存间隔时间的稳定,而scheduleAtFixedRate方法更加侧重于保持执行频率的稳定。
ScheduledExecutorService类
-
代码基本一致,但是ScheduledExecutorService可以保证,task1出现异常时,不影响task2的运行:
-
ScheduledThreadPoolExecutor 则是基于相对时间,而ScheduledThreadPoolExecutor内部是个线程池,所以可以支持多个任务并发执行。
-
该线程在执行任务的时候,遇到执行的任务遇到问题的情况下,也会和timer一样,直接取消该任务的运行,但是可以在该任务的run方法的内部添加try/catch,在测试之后,发现不添加try/catch,任务出现错误直接就死了,但是添加了try/catch,该线程可以继续执行???????
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1); pool.schedule(task1, 100, TimeUnit.MILLISECONDS); pool.scheduleAtFixedRate(task2, 1000 , 2000, TimeUnit.MILLISECONDS);
网友评论