我打算用它来轮询一个可能需要10-15分钟或更长时间的数据库,所以我应该使用计时器。
答案 0 :(得分:8)
如果您希望任务快速完成,但您需要做的事实际上需要更长时间,您可以将其分成两部分。有一个在Timer触发时运行,所以你在正确的时间发生了事情,但是然后将严肃的处理推迟到可能需要的另一个函数(例如,在不同的线程中)。从API来看,Timer任务耗时太长的问题是它们占用线程,可能会延迟后续任务,因此将耗时的处理移动到另一个线程应该避免这个问题。要回答标题中的问题,“快速”将意味着“它应该在Timer需要再次触发之前完成”。
答案 1 :(得分:4)
我假设您在谈论java.util.Timer,而不是Swing特定的那些?
如果我没记错的话,那个计时器只是将执行简单地推迟到一个后台线程,它本质上为JVM中的每个计时器实例提供服务,所以问题可能是一个计时器为每个其他计时器占用了该线程。
如此之快将取决于您的应用程序的其余部分以及您是否使用其他计时器。
一般来说,我避免将它用于任何严重的事情,或者我只是让它产生一个新线程。
答案 2 :(得分:3)
虽然如果你产生一个线程来完成计时器任务的工作,但要注意时间比线程完成时间更快发生的情况,导致工作量不断下降。
答案 3 :(得分:1)
计时器TASK应该快速执行,轮询间隔与其使用无关。确保你不要混淆两者。
答案 4 :(得分:1)
在这种情况下,这意味着您必须完成工作,直到下一个计时器事件发生,否则,将不会处理下一个事件。由于计时器类是全局的,因此您永远无法确定是谁还在使用它(例如,您的数据库驱动程序可能正在使用它来实现超时)。
如果您需要做很长时间的工作,请使用计时器“启动”另一个线程(将项添加到工作队列或在计时器事件处理程序中启动第二个线程)。这将很快为下一个事件释放计时器。
答案 5 :(得分:1)
java.util.concurrent.ScheduledThreadPoolExecutor
是“新java.util.Timer
”。您可以拥有一个(池)线程,这样您就可以容纳长时间运行的任务。即使这样,您也可以考虑检查一下您是否重叠太多。
当然,您可以拥有多个Timer
,并适当地分发您的TimerTask
。
答案 6 :(得分:0)
答案是,这取决于。如果你只是要运行这一个轮询任务,并且在下一个运行开始之前每个运行完成的间隔绰绰有余,那么这个解决方案将正常工作。
问题是当同一个Timer上有多个TimeTask时,因为它们在同一个线程上顺序执行。因此,长时间运行的任务会导致其他任务等待很长一段时间,从而无法创建定时任务。
对于java.util.concurrent包中的更复杂场景以及Quartz等其他库,有更好的解决方案。