У меня есть поле, это использует ntp, и у нас есть несколько программ Java, работающих на них, которые отображают часы. Проблема, которую мы имеем, состоит в том, если что-нибудь ударяет системное время назад все наши таймеры, которые делают вещи как анимационный остановка часов и ожидают, пока системное время не нагоняет назад туда, где это было. Я должен найти способ или обнаружить, когда системное время было изменено назад и сбрасывало все наши таймеры или ряд таймеров, которые могут планировать неоднократно, но все еще быть доказательством, на время изменяющимся.
Как примечание я уже попробовал кварцевый пакет таймера, он имеет ту же проблему как обычные таймеры Java.
Практически все таймеры устанавливают будущее время, а затем регулярно сравнивают текущее время с заданным. Вот почему таймеры "пробуксовывают", когда реальное время идет назад.
К сожалению, ВСЕ таймеры в JVM связаны со временем суток. Например, java.util.Timer выполняет Object.wait(milliSeconds) для события, которое должно произойти. Это сводится к вызову потока, который также выполняет ожидание в течение t миллисекунд. И это всегда относительно "времени суток".
Таким образом, в java нет реального способа сделать это без крутящегося, высасывающего процессор цикла, ожидающего, пока время пойдет назад, чтобы сообщить таймерам, о которых вы заботитесь, о необходимости сброса.
Похоже, что виджет часов сломан. Виджет пользовательского интерфейса должен отображать текущее состояние модели, где модель в данном случае является системным временем. Конечно, для часов вам нужно запланировать repaint ()
каждую секунду, но когда происходит перерисовка, она должна отображать системное время, а не пытаться отслеживать само время.
Этот принцип применим даже к компонентам, не относящимся к пользовательскому интерфейсу. Определите устойчивость компонента к ошибкам синхронизации и создайте фоновый поток, который обновляет компонент с этим интервалом.Однако во время обновления используется системное время, а не независимые внутренние часы.
Обновление:
Базовая ScheduledExecutorService
не страдает от этой проблемы, по крайней мере, на моей платформе.
ScheduledExecutorService worker = Executors.newScheduledThreadPool(1);
worker.schedule(new Runnable() {
public void run()
{
update();
}
}, 100, TimeUnit.MILLISECONDS);