为了账号安全,请及时绑定邮箱和手机立即绑定

Timer和TimerTask与Java中的线程+睡眠

Timer和TimerTask与Java中的线程+睡眠

慕容708150 2019-11-25 14:02:27
我在这里发现了类似的问题,但没有满意的答案。所以再改一下这个问题-我有一项任务需要定期执行(例如间隔1分钟)。与创建一个带有睡眠无限循环的新线程相比,使用Timertask&Timer执行此操作有什么优势?使用timertask-的代码段TimerTask uploadCheckerTimerTask = new TimerTask(){ public void run() {  NewUploadServer.getInstance().checkAndUploadFiles(); }};Timer uploadCheckerTimer = new Timer(true);uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000);使用Thread和sleep-的代码段Thread t = new Thread(){ public void run() {  while(true) {   NewUploadServer.getInstance().checkAndUploadFiles();   Thread.sleep(60 * 1000);  } }};t.start();如果逻辑的执行花费的时间超过间隔时间,我真的不必担心是否会错过某些周期。请对此发表评论。更新:最近,我发现使用Timer与Thread.sleep()之间还有另一个区别。假设当前系统时间是11:00 AM。如果由于某种原因将系统时间回滚到10:00 AM,则Timer将停止执行任务,直到达到11:00 AM,而Thread.sleep()方法将继续执行该任务而没有任何阻碍。这可能是决定这两者之间使用什么的主要决策者。
查看完整描述

3 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

TimerTask的优点是它可以更好地表达您的意图(即代码可读性),并且已经实现了cancel()功能。


请注意,它可以用较短的格式以及您自己的示例编写:


Timer uploadCheckerTimer = new Timer(true);

uploadCheckerTimer.scheduleAtFixedRate(

    new TimerTask() {

      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }

    }, 0, 60 * 1000);


查看完整回答
反对 回复 2019-11-25
?
喵喔喔

TA贡献1735条经验 获得超5个赞

Timer / TimerTask还考虑了任务的执行时间,因此它将更加准确。而且它可以更好地处理多线程问题(例如避免死锁等)。当然,通常最好使用经过测试的标准代码,而不是某些自制的解决方案。


查看完整回答
反对 回复 2019-11-25
?
哔哔one

TA贡献1854条经验 获得超8个赞

Timer 文档中:

Java 5.0引入了java.util.concurrent包,其中的并发实用程序之一是ScheduledThreadPoolExecutor,它是一个线程池,用于以给定的速率或延迟重复执行任务。实际上,它是Timer / TimerTask组合的更通用的替代品,因为它允许多个服务线程,接受各种时间单位,并且不需要子类化TimerTask(只需实现Runnable)。使用一个线程配置ScheduledThreadPoolExecutor使其等效于Timer。

因此,请优先ScheduledThreadExecutor选择Timer

  • Timer使用单个后台线程,该后台线程用于按顺序执行所有计时器任务。因此,任务应快速完成,否则会延迟后续任务的执行。但是,在这种情况下,ScheduledThreadPoolExecutor我们可以配置任意数量的线程,还可以通过提供进行完全控制ThreadFactory

  • Timer使用Object.wait(long)方法可能会对系统时钟敏感。但是ScheduledThreadPoolExecutor不是。

  • 在TimerTask中抛出的运行时异常将杀死该特定线程,从而使Timer死于我们可以处理的地方,ScheduledThreadPoolExecutor从而不会影响其他任务。

  • Timer提供了cancel一种方法来终止计时器并丢弃所有计划的任务,但是它不会干扰当前正在执行的任务并使其完成。但是,如果timer作为守护程序线程运行,则无论我们是否取消它,它都会在所有用户线程完成执行后立即终止。

计时器与Thread.sleep

计时器利用,Object.wait它不同于Thread.sleep

  1. wait可以notify通过另一个线程(使用)来通知正在等待的()线程,但是不能通知正在休眠的线程,只能将其中断。

  2. 等待(和通知)必须在监视对象上同步的块中发生,而睡眠则不必。

  3. 当睡眠状态不释放锁时,等待将释放锁,以等待对象等待。


查看完整回答
反对 回复 2019-11-25
  • 3 回答
  • 0 关注
  • 675 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信