如何以每秒几个固定的速率准确地安排任务

时间:2015-06-10 08:12:11

标签: java multithreading

我目前正在使用

std::function

每秒执行许多任务,在几个线程中也是异步的。问题是,我得到了不准确的信息。例如,当我想在一秒内在第一个线程中执行3个任务,在第二个线程中执行7个任务,在第三个线程中执行5个,有时我会得到4,7,6或3,6,6。这不是处理器在使用更大的数字时无法做到,但我想要每秒执行的任务越多,不准确性就越大。也许是因为 ScheduledFuture<?> schedulerFuture = scheduler.scheduleAtFixedRate(taskMaker, 0 , period, TimeUnit.MICROSECONDS); ScheduledFuture<?> timerFuture = timer.schedule(timeAnalyser, time, TimeUnit.MICROSECONDS); (停止timer)的启动时间与taskMaker不完全相同?

有任何改变建议吗?无论如何使用taskMaker执行如此高频率的任务是否正确?

2 个答案:

答案 0 :(得分:3)

各种ExecutorService的实现使用工作队列,其目的是只要工作作业可用,使用下一个可用线程来执行它,如果没有可用的线程(忙),创建一个新的(在指定的可用线程的限制内,如果达到此数量,则等待线程变为可用),因此您无法控制线程...尤其不是在哪个任务上执行。

对于这样的Executor,你应该考虑实现你自己的Executor,它可能会为你的频率使用Executors.newSingleThreadScheduledExecutor()(3,7和5)。 例如:

ScheduledExecutorService exec1 = Executors.newSingleThreadScheduledExecutor();
ScheduledExecutorService exec2 = Executors.newSingleThreadScheduledExecutor();
ScheduledExecutorService exec3 = Executors.newSingleThreadScheduledExecutor();

exec1.scheduleAtFixedRate(task, 0, 1000 / 3, TimeUnit.MILLISECONDS);
exec2.scheduleAtFixedRate(task, 0, 1000 / 7, TimeUnit.MILLISECONDS);
exec2.scheduleAtFixedRate(task, 0, 1000/5, TimeUnit.MILLISECONDS);

答案 1 :(得分:2)

来自javadoc

  

如果此任务的执行时间超过其周期,那么   后续处决可能会延迟,但不会同时执行   执行。

我认为您可能希望使用schedule而不是scheduleAtFixedRate来自行管理时间(例如,计算一个任务执行后的延迟并在该确切的延迟时间内安排下一个任务)。

另请注意,除非您正在执行大量IO,否则应将池大小保持为服务器上的处理器数量(例如Executors.newScheduledThreadPool(numberOfCpus)