schedule和scheduleAtFixedRate的区别
(2013-11-25 13:03:39)
标签:
杂谈 |
分类: java |
http://my.oschina.net/jeffzhao/blog/73162
http://resource.ajava.org/java/jdk-api-1.6/java/util/Timer.html#schedule(java.util.TimerTask, java.util.Date, long)
http://blog.csdn.net/gtuu0123/article/details/6040159
schedule:下一次的执行时间点=上一次程序执行完成的时间点+间隔时间
scheduleAtFixedRate:下一次的执行时间点=上一次程序开始执行的时间点+间隔时间 ;并且因为前一个任务要执行6秒,而当前任务已经开始执行了,因此两个任务间存在重叠,需要考虑线程同步
timer要注意的问题:
每一个Timer仅对应唯一一个线程。
Timer不保证任务执行的十分精确。
Timer类的线程安全的。
Timer和TimerTask的简单组合是多线程的嘛?不是,一个Timer内部包装了“一个Thread”和“一个Task”队列,这个队列按照一定的方式将任务排队处理,包含的线程在Timer的构造方法调用时被启动,这个Thread的run方法无限循环这个Task队列,若队列为空且没发生cancel操作,此时会一直等待,如果等待完成后,队列还是为空,则认为发生了cancel从而跳出死循环,结束任务;循环中如果发现任务需要执行的时间小于系统时间,则需要执行,那么根据任务的时间片从新计算下次执行时间,若时间片为0代表只执行一次,则直接移除队列即可。
但是是否能实现多线程呢?可以,任何东西是否是多线程完全看个人意愿,多个Timer自然就是多线程的,每个Timer都有自己的线程处理逻辑,当然Timer从这里来看并不是很适合很多任务在短时间内的快速调度,至少不是很适合同一个timer上挂很多任务,在多线程的领域中我们更多是使用多线程中的:
Executors.newScheduledThreadPool
来完成对调度队列中的线程池的处理,内部通过new ScheduledThreadPoolExecutor来创建线程池的Executor的创建,当然也可以调用:
Executors.unconfigurableScheduledExecutorService
方法来创建一个DelegatedScheduledExecutorService其实这个类就是包装了下下scheduleExecutor,也就是这只是一个壳,英文理解就是被委派的意思,被托管的意思。
http://blog.csdn.net/xieyuooo/article/details/8607220
其他:
Java的一个Timer对象本身只有一个线程,如果向他提交多个task,并且某个task相当耗时的话,其他的task即使到了执行时间,仍然会等之前的task执行完毕。更有问题,如果前一个task抛出了异常导致线程终止,后面的task将无法执行。
Java5以后推荐采用java.util.concurrent的ScheduledExecutorService ,至少能避免异常导致线程结束的问题。
(ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1))
如果对时间有比较准确的需要,务必一个ScheduledExecutorService处理一个任务。
另外一说,每天定时执行的任务,用Windows的任务计划,Linux的crond执行一个Java的Application就可以实现,何必用Java的定时器让进程常驻,运行的越久。
http://resource.ajava.org/java/jdk-api-1.6/java/util/Timer.html#schedule(java.util.TimerTask, java.util.Date, long)
http://blog.csdn.net/gtuu0123/article/details/6040159
schedule:下一次的执行时间点=上一次程序执行完成的时间点+间隔时间
scheduleAtFixedRate:下一次的执行时间点=上一次程序开始执行的时间点+间隔时间 ;并且因为前一个任务要执行6秒,而当前任务已经开始执行了,因此两个任务间存在重叠,需要考虑线程同步
timer要注意的问题:
每一个Timer仅对应唯一一个线程。
Timer不保证任务执行的十分精确。
Timer类的线程安全的。
Timer和TimerTask的简单组合是多线程的嘛?不是,一个Timer内部包装了“一个Thread”和“一个Task”队列,这个队列按照一定的方式将任务排队处理,包含的线程在Timer的构造方法调用时被启动,这个Thread的run方法无限循环这个Task队列,若队列为空且没发生cancel操作,此时会一直等待,如果等待完成后,队列还是为空,则认为发生了cancel从而跳出死循环,结束任务;循环中如果发现任务需要执行的时间小于系统时间,则需要执行,那么根据任务的时间片从新计算下次执行时间,若时间片为0代表只执行一次,则直接移除队列即可。
但是是否能实现多线程呢?可以,任何东西是否是多线程完全看个人意愿,多个Timer自然就是多线程的,每个Timer都有自己的线程处理逻辑,当然Timer从这里来看并不是很适合很多任务在短时间内的快速调度,至少不是很适合同一个timer上挂很多任务,在多线程的领域中我们更多是使用多线程中的:
Executors.newScheduledThreadPool
来完成对调度队列中的线程池的处理,内部通过new ScheduledThreadPoolExecu
Executors.unconfigurableScheduledE
方法来创建一个DelegatedScheduledExecut
http://blog.csdn.net/xieyuooo/article/details/8607220
其他:
Java5以后推荐采用java.util.concurrent的ScheduledExecutorService
(ScheduledExecutorService
如果对时间有比较准确的需要,务必一个ScheduledExecutorService
另外一说,每天定时执行的任务,用Windows的任务计划,Linux的crond执行一个Java的Application就可以实现,何必用Java的定时器让进程常驻,运行的越久。
后一篇:守护线程