猿问

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

我在这里发现了类似的问题,但没有满意的答案。所以再改一下这个问题-


我有一项任务需要定期执行(例如间隔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()方法将继续执行该任务而没有任何阻碍。这可能是决定这两者之间使用什么的主要决策者。


慕容708150
浏览 676回答 3
3回答

12345678_0001

TimerTask的优点是它可以更好地表达您的意图(即代码可读性),并且已经实现了cancel()功能。请注意,它可以用较短的格式以及您自己的示例编写:Timer uploadCheckerTimer = new Timer(true);uploadCheckerTimer.scheduleAtFixedRate(    new TimerTask() {      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }    }, 0, 60 * 1000);

喵喔喔

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

哔哔one

从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.sleepwait可以notify通过另一个线程(使用)来通知正在等待的()线程,但是不能通知正在休眠的线程,只能将其中断。等待(和通知)必须在监视对象上同步的块中发生,而睡眠则不必。当睡眠状态不释放锁时,等待将释放锁,以等待对象等待。
随时随地看视频慕课网APP

相关分类

Java
我要回答