2015-11-13 4 views
1

Я хочу занятый цикл ожидания на определенное количество времени, и я проверил следующий код Java, который дает разные выходы на разных прогонах (иногда). Большую часть времени он дает 16 и 0. Это означает, что нельзя доверять оживленному оживанию. Какова причина?Является ли ожидание непоследовательным?

public class Testme { 

    public Testme() { 
     long start = System.currentTimeMillis(); 
     for (int i = 0; i < 10000000L; i++) {} 

     long end = System.currentTimeMillis(); 

     System.out.println(end - start); 
    } 

    public static void main(String[] args) { 
     new Testme(); 
    } 
} 
+2

Этот стиль ожидания всегда будет непоследовательным, поскольку он основан на работе, а не на времени. Это в стороне, 'currentTimeMillis()', вероятно, не так подробно, как вы думаете, (не используйте его для синхронизации, как это). Кроме того, возможности для этого блока должны быть полностью оптимизированы в зависимости от настроек. – AndySavage

+0

Вы имеете в виду, что время на основе busy-wait всегда последовательное? –

+0

Если вы проверите время, это будет намного более последовательным, чем не проверка времени. Для обработки чего-то потребуется определенное количество времени для обработки на основе системы, в которой он работает. – phflack

ответ

0

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

0

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

Вместо того, чтобы скоротать время, было бы лучше использовать Thread.sleep(long time) внутри цикла в то время, чтобы проверить и убедиться, что правильное количество времени прошло

long timeToWait = 500; 
long startTime = System.currentTimeMillis(); 
while(startTime + timeToWait > System.currentTimeMillis()) 
    Thread.sleep(startTime + timeToWait - System.currentTimeMillis()); 
//do stuff after the .5 second wait 

Другой путь, не так хорошо, как Thread.sleep(), это не использовать время цикла до правильного времени

long timeToWait = 500; 
long startTime = System.currentTimeMillis(); 
while(startTime + timeToWait > System.currentTimeMillis()); 
//do stuff after the .5 second wait 

Я бы также не рекомендуется использовать для цикла с обработкой внутри пытаться пройти время из-за pipelining. Контрольный оператор будет летать сверхбыстро, как только процессор поймет, что он почти всегда будет правдивым во время обработки.

+0

Ох! Слава богу, вы сами пришли к моему мнению. На самом деле я использовал ваш код для оживленных ожиданий 10 мс. У меня есть сто рабочих заданий в 10 мс, чтобы обрабатывать столько потоков, но результат настолько ужасен, что многие задания работают меньше 10 мс, даже многие задания работают за 0 мс. Какова причина? –

+0

@MuhammadAbdullah Почему вам нужно, чтобы тайминги были такими маленькими? И что произойдет, если вы просто используете 'Thread.sleep (10)'? Если вы используете любой пример с 'long timeToWait = 10;', тогда он должен всегда ждать не менее 10 мс, если не больше – phflack

+0

Я не использую Thread.sleep(). Я использую ваш второй подход, т. е. вращение. Но многие рабочие места работают менее 10 мс. Я так сильно волнуюсь ... –