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