Java-планировщик, который полностью независим от изменений системного времени - PullRequest
17 голосов
/ 28 января 2012

Использовал Java Timer, затем переключился на ScheduledExecutorService, но моя проблема не исправлена. Поскольку задачи, запланированные до изменения системного времени (через ntpd), не выполняются с указанной задержкой. Не иметь журналов для того же, поскольку ничего не происходит: (.

с использованием 64-битной jre 1.6.0_26 в моей цели на 64-битной Linux.

Обновление: ScheduledExecutorService отлично работает на Windows. Проблема только в 64-битной системе на базе Linux с 64-битной JVM. Работает нормально на 64-разрядная версия Linux работает под управлением 32-разрядной JVM ... странно. Не нашел ни одного упоминания об этом ни в одном блоге.

У IBM JAVA SDK такая же проблема (IBM-Java-СДК-7.0-0.0-x86_64-archive.bin).

Я подал дефект против JDK 7139684 , он был принят, но был закрыт и отмечен дубликат 6900441 . Пожалуйста, проголосуйте за это, если вы чувствуете его стоит исправить ... Я понятия не имею, почему его не исправили более двух лет назад

Вот пример кода, который я использовал для проверки этой проблемы:

package test;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author yogesh
 *
 */
public class TimerCheck  implements Runnable {

    ScheduledExecutorService worker;


    public TimerCheck(ScheduledExecutorService worker) {
        super();
        this.worker = worker;
        this.worker.schedule(this, 1, TimeUnit.SECONDS);
    }

    private static void update() {
        System.out.println("TimerCheck.update() "+new Date(System.currentTimeMillis()));
    }

    @Override
    public void run() {
            update();
            worker.schedule(this, 1, TimeUnit.SECONDS);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        ScheduledExecutorService worker = Executors.newScheduledThreadPool(1);
        new TimerCheck(worker);
    }

}

Ответы [ 2 ]

7 голосов
/ 01 февраля 2012

В JVM есть ошибка для общего планирования во время изменения времени системы в обратном направлении, что также влияет на базовые методы Object.wait & Thread.sleep. Поддерживать работу Java-приложения становится слишком рискованным, когда системное время переключается обратно даже на определенные секунды. Вы никогда не знаете, чем закончится ваше Java-приложение.

Итак, мы решили:

  • Напишите сценарий сторожевого пса (не Java :)) для проверки изменения времени.
  • если время переключится обратно на определенную величину, выключите и перезапустите приложение Java.

Другой возможностью было перейти на 32-битную JVM, но мы используем JNI, и тогда собственные библиотеки, используемые на целевой платформе, не совместимы с 32-битной. Кроме того, по нашему опыту, 32-битная JVM ограничивает нашу цель до кучи 1.6G, что нам совсем не достаточно.

Я знаю, что наше не самое элегантное решение, но до тех пор, пока не будет исправлена ​​JVM или найдено какое-либо лучшее решение, другого пути, похоже, не будет.

Отредактировано: Мы также рассматриваем 1-е предложение Криса в дополнение к вышеуказанному решению:

  • Настройте NTP, чтобы никогда не иметь большого скачка времени. Только убил время медленно. Применяйте только большие прыжки во время простоя вручную.
2 голосов
/ 28 января 2012

Я работал над той же проблемой и не нашел решения. Я посмотрел на Кварц и все встроенные методы JRE. Методы nanotime могут использовать монотонные часы для каждого процессора, но я полагаю, что вы рискуете получить большие скачки, если потоки будут перенесены на другой процессор. Мои выводы были следующие:

  1. Настройте NTP, чтобы никогда не иметь большого скачка времени. Только убил время медленно. Применяйте только большие прыжки во время простоя вручную.
  2. Используйте несколько более короткие тайм-ауты и потребуйте два тайм-аута, чтобы объявить удаленный компьютер мертвым. Это не поможет, если у вас есть только одна системная синхронизация, но может помочь с несколькими системами
  3. специально использует удаленный компьютер для отправки вам периодических пробуждений. Если ваши собственные часы переключаются назад между пробуждениями, то вы знаете, что все ваши таймеры сработают поздно.

По сути, это огромная боль, но серебряных пуль нет.

...