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, 11:59
Кто то понял шестой вопрос? Обьясните пожалуйста, что там происходит?🙂
Ramazan
Уровень 36
Expert
3 апреля 2023, 20:18
9. После посвященных методу yield() задачек, можно отметить, что текущая нить может не прекратить свою работу немедленно. А сам метод это рекомендация для планировщика, которой он нередко пренебрегает. (То, как я понял этот метод)
Griboed
Уровень 30
19 марта 2023, 17:22
Судя по содержанию 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, 09:43
Всякий раз, при изучении этой темы туман опускался на мою голову, но в этот раз, я вдруг обнаружил, что join() это метод класса Thread, а wait() это метод класса Object, то есть работают по разному.
Андрей
Уровень 29
28 января 2021, 08:59
а можно узнать как три нити могут оказаться в synchronized-блоке? в нем же может только одна находиться, разве нет? это про ответ на вопрос 6
One_Two Full Stack Developer
24 марта 2021, 09:50
Скорее всего они вызывают wait в разное время: - 1-ая нить зашла в блок synchronized и вызвала wait, освободив объект - 2-ая нить зашла, вызвала wait - 3-я нить зашла...
Fleckinger
Уровень 28
29 мая 2021, 10:10
Насколько я понял, зайти то могут сколько угодно, а выполняться может только одна. Та которая успеет захватить монитор, получит состояние RUNNABLE и будет выполняться, а остальные получат BLOCKED и будут сидеть и ждать.
SERGEY
Уровень 31
15 января 2022, 12:21
верно. Wait указывает на то, что нить не будет выполнятся пока ее не разбудят, либо не пройдет таймаут. Без этого указателя она могла бы перейти в состояние Runnable, как только бы освободился мьютекс.
Илья
Уровень 30
20 января 2021, 16:30
Единственная тема в java, которая вообще не заходит( Есть ли какое-нибудь учебное пособие "мультипоточность для детей" или типа того?
SERGEY
Уровень 31
15 января 2022, 12:23
это так не работает, скорее нужно брать маленький кусок темы и изучать его до автоматизма. (У меня та же проблема)
Sergey Semendyaev
Уровень 41
9 марта 2020, 09:39
При вызове join(500) текущая нить будет ожидать 500 миллисекунд завершения нити, чей метод join() был вызван.
При вызове wait(500) текущая нить снимет блокировку с синхронизированного объекта, и засыпает на 500 миллисекунд.
Через 500 миллисекунд в обоих случаях нити продолжат работу.
В случае с join(500) добавлю еще , что нить может освободиться и раньше, если другая нить закончит свое выполнение.
Владимир
Уровень 27
30 августа 2020, 18:27
И wait может освободиться раньше, если прилетит notify
Soros
Уровень 39
28 февраля 2020, 14:03
Object monitor = getMonitor()
В каком классе описан метод getMonitor()? Не логичнее ли:
Object monitor = new Object();
?
Сергей Видецких Java Developer в PochtaTech
20 июня 2021, 19:01
getMonitor() дан для примера, по факту стандартного такого метода нет. Можно написать и так как ты предложил Object monitor = new Object();
Сергей Шершавин
Уровень 41
Expert
25 февраля 2020, 16:54
> Через 500 миллисекунд в обоих случаях нити продолжат работу. правильно ли я понимаю, что если notifyAll(), например, прилетит раньше, то в случае wait(500) нить имеет шанс перейти в RUNNABLE ранее 500 миллисекунд? И опять же даже по истечении 500 миллисекунд, где гарантия, что нить не окажется BLOCKED в силу захвата монитора другой нитью в обоих случаях?
Владимир
Уровень 27
30 августа 2020, 18:30
При notify нить может перейти в RUNNABLE или BLOCKED раньше таймаута. И при notify и по истечению таймаута никто не гарантирует, что нить не заблочится, если монитор занят. Всё легко проверяется в идее либо в онлайн сервисах, типа https://www.tutorialspoint.com/compile_java_online.php
Олег Сычев Backend Developer в Elfin
11 ноября 2019, 21:05
"переведет нить из состояния WAITING в состояние RUNNABLE" - нить не перейдет напрямую из состояния WAITING в RUNNABLE. Она сначала в любом случае попадает в BLOCKED-set, где конкурирует с другими нитями, ожидающими входа в synchronized блок (если таковые имеются).
Yuri Serebryakov
Уровень 30
19 января 2020, 13:06
Даже если монитор свободен?
Владимир
Уровень 27
30 августа 2020, 18:34
Только захватив монитор ты можешь вызвать notify, так что да, всегда BLOCKED, и лишь когда вызвавшая notify нить освободит монитор можно перейти в состояние RUNNABLE