Java 高频环路

Java 高频环路,java,Java,我怎样才能创建一个每秒执行10000次的循环,并且有规律的(!)间隔 (副本,但该副本很难找到,未答复,而且非常旧) 我查看了Thread.sleep(long millis)和Thread.sleep(long millis,int nanos),但Oracle在Windows上的J2SE虚拟机的睡眠时间总是比我指定的长1000秒。此外,nanos字段似乎被四舍五入到下一整毫秒(经过验证,这在Thread.java的源代码中是硬编码的) 实验结果: 线程睡眠(0)不睡眠(100%cpu) 线

我怎样才能创建一个每秒执行10000次的循环,并且有规律的(!)间隔

(副本,但该副本很难找到,未答复,而且非常旧)

我查看了
Thread.sleep(long millis)
Thread.sleep(long millis,int nanos)
,但Oracle在Windows上的J2SE虚拟机的睡眠时间总是比我指定的长1000秒。此外,nanos字段似乎被四舍五入到下一整毫秒(经过验证,这在Thread.java的源代码中是硬编码的)

实验结果:

  • 线程睡眠(0)
    不睡眠(100%cpu)
  • 线程睡眠(1)
    平均睡眠1.95毫秒
  • Thread.sleep(2)
    平均睡眠2.95ms
  • 线程。睡眠(0,0)
    不睡眠(100%cpu)
  • Thread.sleep(0,1)
    平均睡眠1.95ms
那么,我怎样才能创建一个循环,以固定的间隔每秒迭代500次以上呢


编辑:我稍微放宽了“常规”要求。如果一个延迟比另一个延迟短4倍(即抖动不是问题),只要最长的延迟是确定的且小于0.1ms,这不是一个大问题。(ScheduledExecutorService的情况并非如此)

我相信您正在寻找(请参见使用示例)

具体地

scheduleAtFixedRate(可运行命令、长初始延迟、长周期、时间单位)

创建并执行一个周期性动作,该动作在给定的初始延迟后首先启用,随后在给定的时间段内启用;也就是说,执行将在initialDelay之后开始,然后是initialDelay+period,然后是initialDelay+2*period,依此类推。


使用TimeUnit.MICROSECONDS.

在Java中计时循环时,永远不要使用
Thread.sleep(long)
,因为这是一种非常不精确的循环方法。尝试改用
javax.swing.Timer
。这里有一个链接

如果你可以将一个核心固定在100%,那么你可以使用这个方法在亚微秒的间隔内获得相当均匀分布的事件。当然,如果您使用此函数达到最大吞吐量,则最好使用成本较低的计时调用替换System.nanoTime()

long nanosBetweenMessages = getSpacing();
long lastSendTime = 0l;
while (true) {
   final long curTimeNanos = System.nanoTime();
   if (curTimeNanos - lastSendTime < nanosBetweenMessages) {
       continue;
   }
   lastSendTime = curTimeNanos;
   sendEvent();
   if (done()) {
       break;
   }
}
long nanoBetweenMessages=getSpacing();
长lastSendTime=0l;
while(true){
final long curTimeNanos=System.nanoTime();
if(Curtimenos-lastSendTime

我刚注意到你的10公里/秒要求。。。目前,我在sendEvent()方法中使用了大量的计算,最大推送速率约为20k/秒。

对于上下文,为什么需要这样做?每秒执行约10000次且有规律(!)间隔的循环为什么要每秒执行如此多的循环??!!如果你需要硬的保证,你需要考虑操作系统和代码。告诉线程睡眠1ms仅仅意味着(1)它进入睡眠状态,(2)它告诉它的老板(JVM或操作系统,取决于线程实现)在1ms过去之前不要唤醒它。但是,如果你的操作系统认为还有更重要的事情要做,那么你的线程的睡眠时间会更长。Zom-B你想要的是一个实时应用程序,java对此不是很好。我想要这个来获取无缓冲事件的数据。如果操作系统不是实时操作系统,应用程序就不能是实时的。(Windows不是)我试过了,得出的结论是它只是在内部使用Thread.sleep(),每次延迟后,它都会赶上未接来电(因此它不是经常出现的)@Zom-B请参阅我对上面问题的评论。您需要应用程序和操作系统内核之间的一切来满足线程需求,对于Java来说,至少包括JVM和操作系统调度器。这根本不是一项容易的任务,因为标准开箱即用操作系统的调度程序粒度约为10ms。您需要大约1ms的时间,请求才能每隔2ms发生一次,其他进程也需要运行,并且您的操作系统和硬件必须非常节省中断和类似的事情。你的问题需要更多的工作,而不是找到一个好的Java库来为你解决这个问题。我忘了把那个要求写在我的帖子里。我正在做的是一个后台服务,不应该以任何方式引人注目,所以100%的cpu是不可能的。同时,我已经实现了一个JNA函数来缓冲输入,以便java能够按照自己的速度接收它们。