JavaRush /Java блог /Архив info.javarush /Уровень 25. Ответы на вопросы к собеседованию по теме уро...
zor07
31 уровень
Санкт-Петербург

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

Статья из группы Архив info.javarush
Уровень 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 Комментарии, дополнения, исправления, замечания - приветствуются =)
Комментарии (36)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Дарья Уровень 39
4 апреля 2023
Кто то понял шестой вопрос? Обьясните пожалуйста, что там происходит?🙂
Ramazan Уровень 36 Expert
3 апреля 2023
9. После посвященных методу yield() задачек, можно отметить, что текущая нить может не прекратить свою работу немедленно. А сам метод это рекомендация для планировщика, которой он нередко пренебрегает. (То, как я понял этот метод)
Griboed Уровень 30
19 марта 2023
Судя по содержанию 6 вопроса, в блоке synchronized у нас не три, а 4 нити: 3 Waiting и 1 Runnable. Далее Runnable нить вызвала метод notifyAll(). Она действительно разбудила 3 ожидающие нити - но они перешли из состояния Waiting не в состояние Runnable, а все перешли в состояние Blocked. У нас нет никаких оснований считать, что при вызове метода notify или notifyAll - вызывающая эти методы нить куда-то вылетает из блока . Как верно написано в описании метода notifyAll: "The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object." Что в переводе на русский означает: "Пробужденные потоки не смогут продолжить работу до тех пор, пока текущий поток не снимет блокировку с этого объекта." Таким образом, после вызова метода notifyAll() или notify(), вызвавший этот метод поток - продолжит работу как ни в чем не бывало, пока не выйдет из метода (либо пока сам не перейдет в режим ожидания, вызвав wait()), а все остальные нити (если вызван метод notifyAll()), или одна нить (если вызван метод notify()) всё так же продолжат ожидать, пока наступит их очередь, но уже не в состоянии Waiting, а в состоянии Blocked.
Михаил Уровень 32
16 ноября 2022
Всякий раз, при изучении этой темы туман опускался на мою голову, но в этот раз, я вдруг обнаружил, что join() это метод класса Thread, а wait() это метод класса Object, то есть работают по разному.
Андрей Уровень 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 блок (если таковые имеются).