2013-04-21 5 views
0

У меня есть следующий код:Thread.sleep себя причудливо

public Move chooseMove(Board board) { 

    // start parallel thread 
    this.tn = new TreeNode(this.myboard, this, null); 
    tn.stop = false; 
    this.curT = (new Thread(tn)); 
    this.curT.start(); 


    try { 
     long startTime = System.currentTimeMillis(); 
     Thread.sleep(4000); 
     System.out.println(System.currentTimeMillis() - startTime); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } finally { 
     tn.stop=true; 
     return getBestMove(); 
    } 
} 

Выход иногда значение, которое больше, чем способ 4000ms как 5400ms, что означает, что поток спит больше, чем следовало бы. Любая помощь? Спасибо.

EDIT: Я понимаю, что нет гарантии того, что Thread # sleep остановится точно после указанной задержки. Однако дополнительные 1400 мс являются большой задержкой. В основном, я реализую агента игрового игрока, и мне нужен способ запустить задачу, а затем вернуть значение на сервер после 5 секунд (иначе сервер завершит игру). Сервер использует java.util.Timer.schedule (задача TimerTask, длительная задержка). Существует только один поток, выполняющий совпадение с основным потоком, который является this.curT в коде выше, так что не очень тяжелая многопоточность.

+2

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

+0

Как часто вы наблюдаете это поведение? Попробуйте запустить только ваш поток с вызовом сна без какого-либо другого кода. –

+0

Если я запускаю Thread.sleep только в одном потоке, тогда он ведет себя корректно. но у меня есть только 2 потока в моем реальном коде, как показано выше. – Mouhyi

ответ

2

От docs.oracle.com: предоставляется

Две перегруженных версий сна: один, который определяет время ожидания до миллисекунды и тот, который определяет время ожидания до наносекунды. Тем не менее, эти не могут быть точными, так как они ограничены средствами, предоставляемыми базовой ОС. Кроме того, период ожидания может быть прерван прерываниями, как мы увидим в следующем разделе. В любом случае, вы не можете предположить, что вызов sleep приостановит поток точно за указанный период времени.

+0

Да, но по моему опыту это @Vito. Любое объяснение, почему он ждет дополнительных 1400 мс? – Gray

+1

1400ms - это долгое время, но такая деятельность, как сбор мусора, может объяснить это.Суть в том, что время паузы в Thread.sleep нельзя полагаться на точность. – DaveH

1

Это обычное поведение и описывается в Thread#sleep Javadoc:

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

Исходя из этого, нет никакой гарантии Thread#sleep останавливая работу нити на количество миллисекунд, указанных в параметре.

1

Thread#sleep сделает вашу нить поспешной за ровно 4 секунды, а затем проснется.
Как только ваш поток проснулся, планировщик ОС помещает его в очередь runnable.
Когда это будет выбрано планировщиком, он станет работает поток i.e будет занимать центральный процессор.
Таким образом, из-за планировщика ОС есть дополнительные задержки, которые могут меняться в зависимости от ОС, загрузки системы и т. Д. Это не связано с Java

+0

Есть ли способ заставить поток начать работать через ровно 4 секунды, оказывая влияние на приоритеты очереди запуска планировщика ОС? – Mouhyi

+0

Вы можете назначить 'MAX_PRIORITY', но по-прежнему не гарантированно получить точный уровень точности, который, как вам кажется, ожидается. Если вам нужно ровно 4 секунды, вы должны делать опрос вместо' sleep'. С 'sleep' вы отказываетесь от процессора и нет гарантии, что вы вернете его за 4 секунды. Гарантируется, что ваш поток будет * просыпаться * через 4 секунды, но больше ничего. – Cratylus

+0

Что вы подразумеваете под «опросом»? – Mouhyi

Смежные вопросы