Java - альтернатива thread.sleep

У меня есть требование приостановить цикл 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;
}

Ответ 1

Попробуйте ScheduledThreadPoolExecutor. Это должно дать более надежные результаты синхронизации.

Ответ 2

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

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

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

Нет ничего, что можно было бы сделать, чтобы контролировать его, чтобы вы не могли точно сказать то, что вы говорите.

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

long now = System.currentTimeMillis();   
while(now < expectedElapsedTime){
    now = System.currentTimeMillis();
}

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

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

fooobar.com/questions/5964/...

Ответ 8

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