2013-10-03 144 views
7

假设您必须执行一项任务,要求每秒执行固定次数(例如20,000)。如何每秒做n次?

你会如何计时?

+3

将您的任务交给'ScheduledExecutorService'执行。 –

+2

我们需要更多信息。当任务'n'超支时会发生什么?同时运行两个任务还是等待? –

+1

每秒做19,999次,稍微加快。 –

回答

10

对于每秒20K次,您需要忙于等待下一个时间间隔。我建议等到下一次它应该运行以消除抖动的影响。

long start = System.nanoTime(); 
long rate = 20000; 
for(long i = 0; ; i++) { 

    // do something 

    long end = start + i * 1000000000L/rate; 
    while(System.nanoTime() < end); 
} 

不能使用内置在调度的原因是最小时间片为100微秒,这是每秒10K倍,在许多平台最小休眠时间为1毫秒。

+1

在非实时操作系统中,使用此技术几乎不可能实现每秒20000次重复。 –

+0

它会在while循环中对Thread.yield()有利吗?或者,这可能会导致等待时间过长,因为没有及时安排(在您称之为“抖动”时增加)? – Cruncher

+0

@StefanoSanfilippo它尽可能地接近你。如果你还隔离了CPU,你将得到小于20微秒的抖动。 –

0

这取决于你在做什么,例如,如果你正在做一些网络,你试图做一些连接,它将取决于连接超时和其他一些因素。如果您正在执行一些基本操作,您将能够控制操作的上限,例如每秒最多20次操作,但由于pc.So中正在运行的其他任务,您将永远无法控制下限。它真的取决于你在做什么,你正在运行的硬件(特别是处理器)以及该计算机的bussy。

1

如果您正在实施一个需要固定时间间隔执行的控制系统,并且您想用Java实现它,请阅读real-time Java

如果您只需要重复执行某些操作并且毫秒级粒度足够,请查看TimerScheduledThreadPoolExecutor

如果您需要更精细的粒度(即每秒超过1000次),但您并不严格要求您的代码以精确的时间间隔执行,那么您可能会得到Peter Lawrey的忙碌解决方案。

1

听起来像来自Guava的RateLimiter的完美工作。

编辑

有一个一目了然成RateLimiter的FPGA实现 - 好,对于如此高的速率并不是一个理想的人选,因为递增它采用同步块和睡觉计数器。但是,如果可以更改粒度,应该没问题,即将您的20.000分成100个包,每个包包含200个项目。