Реализация Thread.sleep ()

Сегодня у меня было интервью, на котором я задал кандидату довольно обычный и основной вопрос о разнице между Thread.sleep () и ] Object.wait () . Я ожидал, что он ответит что-то вроде вроде этого , но он сказал, что эти методы в основном одно и то же, и, скорее всего, Thread.sleep использует Object.wait () внутри него, но сам спящий режим не требует внешней блокировки. Это не совсем правильный ответ, потому что в JDK 1.6 этот метод имеет следующую подпись.

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) . Это имеет смысл для управления планировщиком согласно в этой статье:

Это имеет специальный эффект очистки кванта текущего потока и помещения его в конец очереди для его уровня приоритета. Другими словами, все выполняемые потоки с одинаковым приоритетом (и с более высоким приоритетом) получат возможность работать до того, как полученному потоку в следующий раз будет предоставлено процессорное время.

Таким образом, блок synchronized приведет к ненужным накладным расходам.

Знаете ли вы какие-либо другие причины отказа от использования ожидания по времени в реализации Thread.sleep () ?

28
задан Community 23 May 2017 в 11:46
поделиться

1 ответ

Можно легко сказать, что бритва Оккама режет по-другому. Предполагается, что нормальная / ожидаемая реализация JVM, лежащего в основе JDK, большую часть времени связывает java-потоки с собственными потоками, а перевод потока в спящий режим является фундаментальной функцией базовой платформы. Зачем переопределять это в Java, если код потока все равно будет нативным? Самое простое решение - использовать уже существующую функцию.

Некоторые другие соображения: неоспоримая синхронизация незначительна в современных JVM, но это не всегда было так. Раньше это была довольно «дорогая» операция по приобретению этого монитора объекта.

Если вы реализуете спящий поток внутри кода Java, и способ его реализации также не привязывается к собственному ожиданию потока, операционная система должна продолжать планировать этот поток, чтобы запустить код, который проверяет, пора ли пробуждаться. вверх. Как было отмечено в комментариях, это, очевидно, было бы неверно для вашего примера на современной JVM, но сложно сказать 1) что, возможно, было на месте и ожидалось в то время, когда класс Thread был впервые указан таким образом. и 2) Если это утверждение работает для каждой платформы, возможно, кто-то когда-либо хотел внедрить JVM.

9
ответ дан 28 November 2019 в 03:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: