Сегодня у меня было интервью, на котором я задал кандидату довольно обычный и основной вопрос о разнице между Thread.sleep()
и Object.wait()
. Я ожидал, что он ответит на что-то вроде like this, но он сказал, что эти методы в основном одно и то же, и, скорее всего, Thread.sleep
использует в нем Object.wait()
, но sleep
сам по себе не требует внешней блокировки. Это не совсем правильный ответ, потому что в JDK 1.6 этот метод имеет следующую подпись.Thread.sleep() реализация
public static native void sleep(long millis) throws InterruptedException;
Но моя вторая мысль заключалась в том, что это не так уж и смешно. Для достижения такого же эффекта можно использовать время ожидания. Посмотрите на следующем фрагменте кода:
public class Thread implements Runnable {
private final Object sleepLock = new Object();
// other implementation details are skipped
public static void sleep(long millis) throws InterruptedException {
synchronized (getCurrentThread().sleepLock){
getCurrentThread().sleepLock.wait(millis);
}
}
В этом случае sleepLock
является объектом, который используется, в частности для блока синхронизации внутри sleep
метода. Я предполагаю, что инженеры Sun/Oracle знают о бритве Оккама, поэтому у sleep
есть собственная реализация специально, поэтому мой вопрос заключается в том, почему он использует собственные вызовы.
Единственная идея, которую я придумал, - это предположение, что кто-то может найти полезный вызов, например Thread.sleep(0)
. Это имеет смысл для управления планировщиком согласно this article:
Это имеет особый эффект очистки кванта текущего потока и положить его в конец очереди на ее уровень приоритета. Другими словами, все исполняемые потоки с одним и тем же приоритетом (и с более высоким приоритетом) получат возможность запускать до того, как заданный поток станет следующим заданным временем CPU.
Таким образом, блок synchronized
предоставит ненужные накладные расходы.
Знаете ли вы какие-либо другие причины не использовать время ожидания в Thread.sleep()
?
wait (millis) может просыпаться ложно (рано), тогда как сон не просыпается рано, если не прерывается. –
Проверен ли прерванный флаг во время вызова sleep(), чтобы исключить и вернуть? Или каким-то образом этот вызов идет и к планировщику, а затем планировщик знает, как закончить сон потока? –
Мне было бы больше интересно узнать, знают ли они, как правильно обрабатывать InterruptedException. –