Пожалуйста, посмотрите на раздел «Изменить» моего вопроса.

а, которая меня раздражает, такая же, какэтот билет, По сути, если вы измените часы ОС на дату в прошлом, все потоки, которые спали во время изменения, не будут активированы.

Приложение, которое я разрабатываю, предназначено для работы 24/24, и мы хотели бы иметь возможность изменять дату ОС, не останавливая ее (например, переключаться с летнего времени на зимнее время). На данный момент происходит то, что когда мы изменяем дату на прошлое, некоторые части приложения просто замирают. Я заметил это на нескольких машинах, в Windows XP и Linux 2.6.37, а также с недавней JVM (1.6.0.22).

Я пробовал много спящих примитивов Java, но все они имеют одинаковое поведение:

Thread.sleep (длинный)Thread.sleep (long, int)Object.wait (длинный)Object.wait (long, int)Thread.join (длинный)Thread.join (long, int)LockSupport.parkNanos (длинный)java.util.Timerjavax.swing.Timer

Теперь у меня нет идеи обойти эту проблему. Я думаю, что я ничего не могу сделать, чтобы предотвратить замерзание спящих нитей. Но я хотел бы, по крайней мере, предупредить пользователя при обнаружении опасного изменения системных часов.

Я придумал поток мониторинга, который обнаруживает такие изменения:

    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            long ms1 = System.currentTimeMillis();
            long ms2;
            while(true) {
                ms2 = ms1;
                ms1 = System.currentTimeMillis();
                if (ms1 < ms2) {
                    warnUserOfPotentialFreeze();
                }
                Thread.yield();
            }                    
        }
    });
    t.setName("clock monitor");
    t.setPriority(Thread.MIN_PRIORITY);
    t.setDaemon(true);
    t.start();

Проблема заключается в том, что это приводит к росту нагрузки на приложение с 2% до 15% в режиме ожидания.

У вас есть идея обойти исходную проблему, или вы можете придумать другой способ контролировать появление замораживания потоков?

редактировать

Инго предложил не трогать системные часы. Я согласен, что это вообще не нужно. Проблема в том, что мы не контролируем, что наши клиенты делают со своими компьютерами (мы планируем продать сотни копий).

Хуже того: одна из наших машин демонстрирует эту проблему без какого-либо ручного вмешательства. Я предполагаю, что ОС (Windows XP) регулярно синхронизирует свои часы с часами RTC, и это заставляет часы ОС возвращаться во времени естественным образом.

эпилог

Я узнал, что некоторые утверждения в моем вопросе были неправильными. На самом деле есть две отдельные причины, связанные с моей первоначальной проблемой. Теперь я могу точно сказать две вещи:

Только на моей машине (archlinux с ядром 2.6.37 с OpenJDK 64 бит 1.6.0_22),Thread.sleep, Object.wait, Thread.join, LockSupport.parkNanos имеют ту же проблему: они просыпаются только тогда, когда системные часы достигают «целевого» времени пробуждения. Тем не менее, простойsleep в моей оболочке проблема не проявляется.

На всех машинах, которые я тестировал (включая мою),java.util.Timer а такжеjava.swing.Timer имеют ту же проблему (они блокируются, пока не будет достигнуто «целевое» время).

Итак, что я сделал, это то, что я заменил все JavaTimer более простой реализацией. Это решает проблему для всех машин, кроме моей (я просто надеюсь, что моя машина - исключение, а не правило).

Ответы на вопрос(5)

Ваш ответ на вопрос