Thread.sleep ждет больше, чем ожидалось - PullRequest
9 голосов
/ 23 мая 2011

следующий код:

long msBefore = System.currentTimeMillis();
//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
try
{Thread.sleep(200);
} catch (InterruptedException e){}
System.out.println("Time: " + (System.currentTimeMillis() - msBefore));

отпечатков:

Time: 578
Time: 594
Time: 625
Time: 640
Time: 641
Time: 609
Time: 625
Time: 625
Time: 610
Time: 609
Time: 625
Time: 625
Time: 422
Time: 625
Time: 594
Time: 609
Time: 625
Time: 594
Time: 594
Time: 625

В чем проблема ??

Ответы [ 4 ]

8 голосов
/ 23 мая 2011

У меня есть требование отправлять n сообщений в секунду, я думаю, что ожидание / уведомление не подходят, верно?

Если у вас жесткие требования к времени, то вы собираетесьнеобходимо использовать реализацию Java в реальном времени.Основные реализации Java и SE не подходят для сложных приложений реального времени.

Существуют различные приемы, которые вы можете использовать для удовлетворения таких требований "большую часть времени" ... но если ваше приложение / система перегружены, выначинаются пропуски требуемой скорости передачи сообщений.

Эта реальная проблема не в точности таймеров, а в том, что планировщик не в реальном времени не гарантирует (и не может) планировать поток длязапустить, как только истечет таймер.

7 голосов
/ 23 мая 2011

Здесь нет проблем.От javadoc:

в зависимости от точности системы и планировщиков.

Обычно плохой дизайн полагаться на интервал ожидания, поскольку он может отличаться в разных системахи реализации JVM.Вместо этого используйте wait () и notify (), а лучше - используйте пакет java.util.concurrent.

0 голосов
/ 19 июня 2012

Если вам действительно нужна фиксированная скорость передачи сообщений, используйте что-то вроде спин-блокировки.Он будет потреблять одно ядро ​​процессора, но приблизится.

long nextTime = System.currentTimeMillis() + interval;
while (keepRunning) {
   while (nextTime - System.currentTimeMillis() > 0)
       ;
   sendMessage();
   nextTime += interval;
}
0 голосов
/ 26 февраля 2012

Вы не учитываете время, затрачиваемое на обработку.

    try {
        long processingStart = System.currentTimeMillis();

        long processingFinish = System.currentTimeMillis();
        long processTime = 600 - (processingFinish - processingStart);
        Thread.sleep(processTime);

    } catch (InterruptedException ex) {

    }
...