Начать событие по заданному времени - PullRequest
0 голосов
/ 20 января 2019

Я занимался исследованиями и изо всех сил стараюсь выбрать лучший вариант. Я использую эскиз обработки, который выполняет код Java, и я хочу запустить анимацию на нескольких компьютерах (OS X и Windows) одновременно. Основная идея состоит в том, чтобы отправить сообщение OSC на каждый компьютер, и после получения сообщения они сохранят currentTime плюс временной интервал (скажем, через 10 секунд). И каждый компьютер отслеживает currentTime, и когда он достигает предполагаемого времени, они запускают анимацию. Теперь я не могу понять, какую систему мне использовать. System.currentTimeMillis () или System.nanoTime (); Я уже проверил с двумя компьютерами (оба системы), и это похоже на работу. Оба компьютера являются OS X, но я никогда не пробовал с Windows, и кажется, что для System.currentTimeMillis () может быть задержка 50 мс. Я действительно запутался в этом вопросе. Кто-то может мне объяснить или выделить. заранее спасибо

1 Ответ

0 голосов
/ 20 января 2019

Simultanous симуляции на двух или более компьютерах сложно по некоторым причинам.

  • Прежде всего, я хотел бы убедиться, что все подключенные компьютеры синхронизируют свои часы с NTP. (Подробнее https://en.wikipedia.org/wiki/Network_Time_Protocol) Тогда самая большая разница составляет не более 50 мс, насколько я знаю. В противном случае каждый подход потерпит неудачу из-за различий в часах.
  • Во-вторых, часы в разных системах имеют разную точность. Рекомендую почитать блог Алексея Шипилева: https://shipilev.net/blog/2014/nanotrusting-nanotime/. Речь идет о точности часов на машинах в целом.
  • В-третьих, вы должны знать, что у Linux есть циклический сдвиг 1 мс, а у Windows - 10-15 мс. Поэтому 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;
            }
        }
    }
    

Однако, он будет занят вашим процессором и не всегда будет надежным (но в большинстве случаев).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...