Java:for循环的第一次迭代需要更长的时间

Java:for循环的第一次迭代需要更长的时间,java,for-loop,midi,lag,synthesizer,Java,For Loop,Midi,Lag,Synthesizer,我正在编写一些代码来使用Java中的MIDI库进行测试,遇到了一个问题。在第一个音符之后,音符之间的停顿比在所有其他音符之后要长得多(事实上几乎是原来的两倍)。我看不出任何原因,因为已经生成了音符序列(因此它不必在循环的第一次迭代中执行这些计算,它只是在播放音符) 我想我可能在过去的模拟中也遇到过这个问题,在没有任何解释的情况下,我可以发现,几乎100%的勾号长度只在第一个勾号上执行计算,然后在所有后续迭代中只使用了大约2% 主要代码(摘录): 没有指定第一个循环的“if”语句,因此所有注释的延

我正在编写一些代码来使用Java中的MIDI库进行测试,遇到了一个问题。在第一个音符之后,音符之间的停顿比在所有其他音符之后要长得多(事实上几乎是原来的两倍)。我看不出任何原因,因为已经生成了音符序列(因此它不必在循环的第一次迭代中执行这些计算,它只是在播放音符)

我想我可能在过去的模拟中也遇到过这个问题,在没有任何解释的情况下,我可以发现,几乎100%的勾号长度只在第一个勾号上执行计算,然后在所有后续迭代中只使用了大约2%

主要代码(摘录):

没有指定第一个循环的“if”语句,因此所有注释的延迟肯定是一致的,因为所有迭代执行的计算数量应该相同。请注意,时间变量只是为了测试目的,在我加入这些变量之前,其效果是显而易见的


EDIT:我还应该提到,生成的输出显示循环的每次迭代花费了预期的200(偶尔201)毫秒。这似乎表明没有间隙-但我每次运行代码时都能清楚地听到间隙。

既然你有睡眠,你应该计算你应该睡多长时间,而不是每次尝试睡相同的时间-计算你实际需要多长时间才能弹奏下一个音符,睡那么多。i、 e

    long tic = System.currentTimeMillis();
    player.playNote(10, notes[i]);
    long time_spent = System.currentTimeMillis() - tic;
    Thread.sleep(200 - time_spent);

目前公开的代码很难说。我怀疑第一个
allnotesof
调用可能是初始化一些需要时间的东西。在开始实际播放之前,您是否尝试过调用它,可能是加入调用它的线程?我刚刚尝试了一下,但似乎没有任何区别。然后,可能是第一次
noteOn
调用。。。就像我说的,如果不知道
MidiPlayer
的实际功能,就很难知道会出什么问题。需要注意的一点是,
Thread.sleep
调用“取决于系统计时器和调度程序的精度和准确性”(请参见API),这意味着您当前的线程可能不会一直保持精确的睡眠时间。或者,可能是您的代码运行良好,但是,过去常常与MIDI接收器通话的驱动程序需要一些时间来“预热”。我刚刚尝试将延迟从200ms缩短到125ms,并观察到有一段时间之后,播放速度也明显快于其他时间-计时有问题,但在多次运行时似乎是一致的。而且不仅仅是开始迭代时所特有的。
public void playNote(int channel, int note) {
    channels[channel].allNotesOff();
    channels[channel].noteOn(note + 60,  volume);
}
    long tic = System.currentTimeMillis();
    player.playNote(10, notes[i]);
    long time_spent = System.currentTimeMillis() - tic;
    Thread.sleep(200 - time_spent);