Пользователь zor07
zor07
31 уровень
Санкт-Петербург

Уровень 25. Ответы на вопросы к собеседованию по теме уровня

Статья из группы Архив info.javarush.ru
Уровень 25. Ответы на вопросы к собеседованию по теме уровня - 1
  1. Назовите все состояния объекта Thread?

    • NEW
    • RUNNABLE
    • BLOCKED
    • WAITING
    • TIMED_WAITING
    • TERMINATED
  2. В какие состояния может перейти нить, при входе в блок synchronized?

    • RUNNABLE
    • BLOCKED

    В RUNNABLE, если блок кода, помеченный synchronized, не занят другой нитью. Иначе наша нить получит состояние BLOCKED и будет ждать освобождения объекта-мютекса.

  3. В какое состояние перейдет нить, при вызове метода wait()?

    Вызов этого метода переводит нить в состояние WAITING.
    Метод wait() можно вызвать только внутри блока synchronized у объекта-мютекса, который был «залочен (заблокирован)» текущей нитью, в противном случае метод выкинет исключение IllegalMonitorStateException.

    
    Object monitor = getMonitor();
    synchronized(monitor)
    {
     …
     monitor.wait();
     …
    }
    

    При вызове метода wait(), текущая нить снимает блокировку с объекта monitor, и переходит в состояние WAITING, ожидая вызова метода monitor.notify() или monitor.notifyAll() другой нитью. Как только это произойдет, нить проснется и если монитор не был занят, то захватит его и продолжит работу.
    Если монитор окажется занят другой нитью, текущая нить перейдет в состояние BLOCKED.

  4. В какое состояние перейдет нить, при вызове метода wait(500)?

    Вызов этого метода переводит нить в состояние TIMED_WAITING.
    По аналогии с методом wait(), wait(timeout) можно вызвать только внутри блока synchronized у объекта-мютекса, который был «залочен (заблокирован)» текущей нитью.

    
    Object monitor = getMonitor();
    synchronized(monitor)
    {
     …
     monitor.wait(500);
     …
    }
    

    При вызове метода wait(), текущая нить снимает блокировку с объекта monitor, и засыпает на 500 миллисекунд. Объект monitor может быть захвачен другой нитью.
    Через 500 миллисекунд нить проснется и если monitor не был занят, то захватит его и продолжит работу.
    Если монитор окажется занят другой нитью, текущая нить перейдет в состояние BLOCKED.

    В какое состояние перейдет нить, при вызове метода notify()?

    
    Object monitor = getMonitor();
    synchronized(monitor)
    {
     …
     monitor.wait();
     …
    }
    

    После monitor.wait(), нить перейдет в состояние WAITING. Метод notify(), вызванный другой нитью у объекта monitor переведет нить из состояния WAITING в состояние RUNNABLE, если объект monitor не будет захвачен другой нитью, иначе в состояние BLOCKED.

  5. В какое состояние перейдет нить, при вызове метода notifyAll()?

    notifyAll() "пробудет" все нити. Одна из всех "спящих" (WAITING) нитей перейдет в состояние RUNNABLE, захватит монитор используемого объекта и продолжит свою работу. Остальные окажутся в состоянии BLOCKED. Как только первая "проснувшаяся" нить отпустит монитор, который все остальные ожидают, её участь повторит следующая нить (произвольная нить из состояния BLOCKED перейдет в состояние RUNNABLE). Это будет продолжаться до тех пор, пока все "пробужденные" нити не покинут состояния BLOCKED.

  6. Три нити в блоке synchronized вызвали wait() у объекта-мютекса. В какое состояние перейдут эти нити, если четвертая нить вызовет notifyAll()?

    Две из них перейдут в состояние BLOCKED, одна в состояние RUNNABLE

  7. Чем отличается join(500) от wait(500)?

    Несмотря на то, что и join(500) и wait(500) переведут текущую нить в состояние TIMED_WAITING, между ними существенные различия:
    join(500) вызывается у нити, wait(500) вызывается внутри синхронизированного блока у объекта, по которому данный блок синхронизирован.
    При вызове join(500) текущая нить будет ожидать 500 миллисекунд завершения нити, чей метод join() был вызван.
    При вызове wait(500) текущая нить снимет блокировку с синхронизированного объекта, и засыпает на 500 миллисекунд.
    Через 500 миллисекунд в обоих случаях нити продолжат работу.

  8. Чем отличается wait(500) от sleep(500)?

    sleep(500) вызывается у нити, wait(500) вызывается внутри синхронизированного блока у объекта, по которому данный блок синхронизирован.
    При вызове sleep(500) текущая нить будет ожидать 500 милисекунд, затем продолжит свою работу.
    При вызове wait(500) текущая нить снимет блокировку с синхронизированного объекта, и засыпает на 500 миллисекунд.

  9. В какое состояние перейдет нить при вызове метода yield()?

    При вызове метода yield() – текущая нить «пропускает свой ход» и java сразу переключается на выполнение следующей нити. Нить из состояния running переходит в состояние ready. Состояния running & ready – это подсостояния состояния RUNNABLE.

PS Комментарии, дополнения, исправления, замечания - приветствуются =)
Комментарии (28)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
Андрей 29 уровень, Москва
28 января 2021
а можно узнать как три нити могут оказаться в synchronized-блоке? в нем же может только одна находиться, разве нет? это про ответ на вопрос 6
Илья 30 уровень, Дзержинск
20 января 2021
Единственная тема в java, которая вообще не заходит( Есть ли какое-нибудь учебное пособие "мультипоточность для детей" или типа того?
Sergey Semendyaev 41 уровень, Краснодар
9 марта 2020

При вызове join(500) текущая нить будет ожидать 500 миллисекунд завершения нити, чей метод join() был вызван.
При вызове wait(500) текущая нить снимет блокировку с синхронизированного объекта, и засыпает на 500 миллисекунд.
Через 500 миллисекунд в обоих случаях нити продолжат работу.
В случае с join(500) добавлю еще , что нить может освободиться и раньше, если другая нить закончит свое выполнение.
Soros 39 уровень, Харьков
28 февраля 2020

Object monitor = getMonitor()
В каком классе описан метод getMonitor()? Не логичнее ли:

Object monitor = new Object();
?
Сергей Шершавин 41 уровень, Москва Expert
25 февраля 2020
> Через 500 миллисекунд в обоих случаях нити продолжат работу. правильно ли я понимаю, что если notifyAll(), например, прилетит раньше, то в случае wait(500) нить имеет шанс перейти в RUNNABLE ранее 500 миллисекунд? И опять же даже по истечении 500 миллисекунд, где гарантия, что нить не окажется BLOCKED в силу захвата монитора другой нитью в обоих случаях?
Олег Сычев 40 уровень, Москва
11 ноября 2019
"переведет нить из состояния WAITING в состояние RUNNABLE" - нить не перейдет напрямую из состояния WAITING в RUNNABLE. Она сначала в любом случае попадает в BLOCKED-set, где конкурирует с другими нитями, ожидающими входа в synchronized блок (если таковые имеются).
Anton Stezhkin 35 уровень
21 октября 2019
"Чем отличается join(500) от wait(500)? Несмотря на то, что и join(500) и wait(500) переведут текущую нить в состояние TIMED_WAITING, между ними существенные различия: join(500) вызывается у нити, wait(500) вызывается внутри синхронизированного блока у объекта, по которому данный блок синхронизирован. При вызове join(500) текущая нить будет ожидать 500 миллисекунд завершения нити, чей метод join() был вызван. При вызове wait(500) текущая нить снимет блокировку с синхронизированного объекта, и засыпает на 500 миллисекунд. Через 500 миллисекунд в обоих случаях нити продолжат работу." - Разве нити, которые ждут завершения нити, вызвавшей join(500) не попытаются выйти из TIMED_WAITING, если нить, вызвавшая join(500) завершится?
Иван Сапронов 32 уровень, Ставрополь
11 мая 2019
Спасибо за статью. Можно вопрос немного не по теме... скажите пожалуйста, как вы делаете выделенный текст? Это опция доступна к тексту только при создании статьи или её можно как-то применять в тексте комментария?
hidden #1281202 41 уровень
6 апреля 2019
Думаю, что вопрос номер 5 нужно перефразировать с "В какое состояние перейдет нить, при вызове метода notifyAll()?" на "В какое состояние перейдут нити в блоке synchronized при вызове метода notifyAll()?". Ведь, если я не ошибаюсь, notify() & notifyAll() "пробуждают" нити из состояния WAITING & TIMED_WAITING, но ведь в эти состояния их может ввести не только wait() блока synchronized, а также join(), sleep(), которые не обязаны находиться в блоке синхронизации. Поэтому я нашёл этот вопрос недостаточно точным.
Александр Колосов 36 уровень, Санкт-Петербург
6 февраля 2019
Встречный вопрос к Вопросу №6. А если 4-я нить, все еще будет блокировать монитор?