2015-08-18 19 views
0

scheduleAtFixedRate这样的工作是如何工作的?它在幕后如何工作,使用它有什么惩罚?幕后的Java ScheduledExecutorService

更具体地说,我有一个任务,我想定期运行,比如说每12小时。这段时间并不严格,所以我的第一本能是检查每个请求(tomcat服务器),如果它已经超过了上次执行任务的12个小时以上,并且如果是,执行它并重置定时器。其缺点是我必须对每个请求进行一次小小的检查,确保任务只运行一次(使用信号量或类似的东西),并且如果没有请求,任务可能无法在很长时间内执行。

scheduleAtFixedRate可以更容易地安排一个循环任务,但由于我不知道它是如何实现的,我不知道性能的影响是什么。是否有线程不断检查任务是否由于运行?等

编辑:Timer.java,有一个mainLoop函数,在我的理解,是这样的(过于简化):

while(true) { 
    currentTime = System.currentTimeMillis(); 
    if(myTask.nextExecutionTime == currentTime) myTask.run(); 
} 

这会不会循环尝试跑得快尽可能使用一吨CPU(我知道,显然不是,但为什么)?在那里没有Thread.sleep来减慢速度。

+1

使用像[quartz-scheduler](http://quartz-scheduler.org/)或类似的库。或者使用'ScheduledExecutorService'滚动你自己的。 –

+1

“因为我不知道它是怎么做的”查看源代码,也许? –

回答

1

如果你想弄清楚它是如何工作的,你可以阅读代码。

在CPU和内存方面,使用ScheduledExecutorService会有一些开销,但是在小时,分钟,秒甚至毫秒的范围内,它可能无需担心。如果你的任务在微秒范围内运行,我会考虑更轻的重量。

总之,开销可能太小,你不会注意到。它给你带来的好处是易用性,而且很可能是值得的。

+0

另一个需要注意的是jdk的ScheduledThreadPoolExecutor实现使用同步队列。因此,虽然它使一个体面的*调度程序*因为在提交任务时锁定争用而将其用作双重角色*执行程序将是一个可怕的想法。 – the8472

+0

@ the8472你必须以很高的速度提交任务。如果你每小时有一个,它不会。 –

+0

如果你做UDP网络连接并提交超时例如这可能很重要。此外,重复的任务必须重新提交自己,因此,即使只提交一次,如果您有多个任务在多个线程上弹出或关闭工作队列,仍然可以与锁进行竞争。最后但并非最不重要的一点是,STPE也是一个普通的线程池,如果它被用作('execute()'/'submit()'),你也会产生这种开销。 – the8472

相关问题