在给定时间范围内开始活动

时间:2019-01-19 21:49:14

标签: java time

我一直在研究,并且正在努力选择最佳选择。我正在使用运行Java代码的处理草图,并且想同时在多台计算机(OS X和Windows)中启动动画。基本思想是向每台计算机发送OSC消息,当它们收到消息后,它们将存储currentTime加上时间跨度(假设10秒后)。每台计算机都会跟踪currentTime,并在达到预期时间时开始动画。现在,我无法确定应该使用哪个系统。 System.currentTimeMillis()或System.nanoTime();我已经在两台计算机(均为系统)上进行了测试,它似乎可以工作。这两台计算机都是OS X,但我从未尝试过使用Windows操作系统,似乎System.currentTimeMillis()可能会滞后50毫秒。在这件事上我真的很困惑。可以给我解释或强调的人。 预先感谢

1 个答案:

答案 0 :(得分:0)

由于某些原因,在两台或更多台计算机上同时进行模拟非常棘手。

  • 首先,我要确保所有连接的计算机都将其时钟与NTP同步。 (查看更多https://en.wikipedia.org/wiki/Network_Time_Protocol) 据我所知,最大的区别是最多50ms。 否则,由于时钟的差异,每种方法都会失败。
  • 第二,不同系统上的时钟具有不同的精度。我建议您阅读Alexey Shipilev的博客:https://shipilev.net/blog/2014/nanotrusting-nanotime/。通常,这与机器上时钟的准确性有关。
  • 第三,您需要知道Linux的循环幻灯片为1ms,Windows的循环幻灯片为10-15ms。因此,Thread.sleep(...)将无法在更短的时间范围内正常运行。 如果您想在更短的时间范围内工作,则需要执行一种“忙碌的等待”,这很丑陋但有必要:

    public class SleepUtil {
    
        public static final long MIN_PRECISION_IN_MICROS = 15L;
    
        public static void main(String[] args) {
            long before = System.nanoTime();
            while (true) {
                final long after = System.nanoTime();
                long diff = (after - before) / 1000l;
    
                before = after;
                System.out.println(diff + " micros");
    
                SleepUtil.sleepMicros(500);
            }
        }
    
        private static void sleepMicros(int waitTimeInMicros) {
            final long startTimeInNanos = System.nanoTime();
            long elapsedTimeInMicros = 0L;
            while (elapsedTimeInMicros < waitTimeInMicros - MIN_PRECISION_IN_MICROS) {
                elapsedTimeInMicros = (System.nanoTime() - startTimeInNanos) / 1000L;
            }
        }
    }
    

但是,它将使您的CPU繁忙,并且并不总是可靠的(但是大多数时候)。