Java - альтернатива thread.sleep - PullRequest
20 голосов
/ 04 февраля 2012

У меня есть требование приостановить цикл while на определенное количество миллисекунд. Я пытался использовать Thread.sleep (продолжительность), но это не точно, особенно в цикле. Точность в миллисекундах важна в моей программе.

Вот алгоритм, в котором я не хочу возвращаться, чтобы проверить состояние, пока expectedElapsedTime не пройдет.

while (condition) {
    time = System.currentTimeMillis();
    //do something
    if (elapsedTime(time) < expectedElapsedTime) ) {
        pause the loop  // NEED SUBSTITUTE FOR Thread.sleep()
    }
    // Alternative that I have tried but not giving good results is 
    while ((elapsedTime(time) < expectedElapsedTime)) {
        //do nothing
    }
}

long elapsedTime(long time) {
   long diff = System.currentTimeMillis() - time;
   return diff;
}

Ответы [ 8 ]

10 голосов
/ 04 февраля 2012

Попробуйте ScheduledThreadPoolExecutor . Предполагается, что результаты будут более надежными.

8 голосов
/ 04 февраля 2012

Что вы ожидаете?

Если вы перейдете в спящий режим, то после того, как ваш процесс снова запустится, ему придется ждать, пока планировщик потока не запланирует его снова.

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

Вы ничего не можете сделать, чтобы контролировать его, поэтому вы не можете иметь точность, которую говорите.

Для вашего случая я бы предложил вращающуюся петлю.

long now = System.currentTimeMillis();   
while(now < expectedElapsedTime){
    now = System.currentTimeMillis();
}
6 голосов
/ 18 сентября 2012

Java не является системой реального времени, вы не можете заставить поток уйти и вернуться в столь сжатые сроки. Чтобы запланировать выполнение вашей программы до миллисекунды, вам нужно использовать другую платформу - например, simpleRTJ или Java Real-Time extension .

2 голосов
/ 04 февраля 2012

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

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

1 голос
/ 13 декабря 2014

Решение состоит в том, чтобы использовать обработчик с работоспособным объектом и использовать метод postDelayed. Пример:

new Handler().postDelayed(new Runnable() {
public void run () {
    // Do delayed stuff!
}
}, 5000L); //5 seconds delay 

https://stackoverflow.com/a/21680858

1 голос
/ 04 марта 2014

Если вы хотите быть точным со звуками, вы используете секвенсор и устанавливаете темп в BPM: sequencer.setTempoInBPM (120);

1 голос
/ 04 февраля 2012

Вы можете реализовать механизм ожидания / уведомления и передать другому потоку ответственность за уведомление другого потока в состоянии ожидания о том, что количество времени прошло и что оно может продолжаться ...

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

0 голосов
/ 07 февраля 2014

Не забывайте о паузах сборщика мусора. Это может превзойти все ваши планы

...