ScheduledThreadPoolExecutor выполняет неправильное время из-за несоответствия времени процессора - PullRequest
5 голосов
/ 30 апреля 2010

Я планирую задачу, используя объект ScheduledThreadPoolExecutor. Я использую следующий метод:

public ScheduledFuture<?> schedule(Runnable command, long delay,TimeUnit unit) 

и установите задержку на 30 секунд (задержка = 30 000 и единица измерения = TimeUnit.MILLISECONDS). Иногда моя задача возникает сразу, а иногда - 70 секунд.

Я считаю, что ScheduledThreadPoolExecutor использует специфичные для процессора часы. Когда я запускаю тесты, сравнивающие System.currentTimeMillis (), System.nanoTime () [который зависит от процессора], я вижу следующее

расписание: 1272637682651мс, 7858346157228410нс

Выполнить: 1272637682667мс, 7858386270968425нс

разница составляет 16 мс, но 4011374001 нс (или 40,113 мс)

так что, похоже, что расхождение между двумя тактовыми частотами процессора составляет 40 секунд

Как мне решить эту проблему в коде Java? К сожалению, это клиентская машина, и я не могу изменить их систему.

1 Ответ

2 голосов
/ 02 мая 2010

Да, вы правы, что ScheduledThreadPoolExecutor использует System.nanoTime (). И вы также правы, что System.nanoTime () зависит от конкретного экземпляра системы. Если ваш процесс мигрирует между расписанием и выполнением, вам не повезло. (Я не думаю, что миграция между процессорами в многопроцессорной системе будет иметь значение, но, может быть, это имеет значение? Конечно, это будет иметь значение, если вы работаете в виртуальной машине, а виртуальная машина мигрирует между хостами).

Я думаю, что единственным реальным решением в этом случае является использование чего-то другого, кроме ScheduledThreadPoolExecutor ... Это не так просто, как просто изменить ScheduledThreadPoolExecutor.now (). AbstractQueuedSynchronizer $ ConditionObject.awaitNanos () также использует System.nanoTime ().

Один из моих проектов использует Кварц для планирования заданий, и я никогда не видел проблемы, которую вы описываете с этой библиотекой. Я не знаю деталей реализации (может быть, он просто использует System.nanoTime (), но может и нет?).

...