undefined

Нюансы работы

Java Multithreading
7 уровень , 8 лекция
Доступна

— Привет, Амиго!

И еще пара деталей. Так сказать практических советов.

Пусть у тебя есть метод, который что-то ждет и засыпает, пока условие не выполнено.

Если коллекция пустая, то ждем
public synchronized Runnable getJob()
{
 if (jobs.size()==0)
  this.wait();

 return jobs.remove(0);
}

В документации по Java очень старательно советуют вызвать метод wait в цикле:

Если коллекция пустая, то ждем
public synchronized Runnable getJob()
{
 while (jobs.size()==0)
  this.wait();

 return jobs.remove(0);
}

Зачем это надо. Дело в том, что если нить разбудили – это еще не значит, что условие выполнится. Может, там таких спящих нитей было два десятка. Разбудили всех, а задание забрать сможет только одна.

Грубо говоря, могут быть «ложные побудки». Хороший разработчик должен учитывать это дело.

— Ясно. А не проще ли тогда использовать просто notify?

— А если в списке больше чем одно задание? Notify обычно советуют использовать ради оптимизации. Во всех остальных случаях рекомендуют использовать метод notifyAll.

— Ок.

— Но и это еще не все. Во-первых, может возникнуть ситуация, когда кто-то унаследовался от твоего класса, добавил туда свои методы и тоже использует wait/notifyAll. Т.е. может быть ситуация, когда на одном объекте висят независимые пары wait/notifyAll, которые друг о друге не знают. Поэтому что надо делать?

— Всегда вызывать wait в цикле и проверять, что условие выхода из цикла действительно выполнилось!

— Правильно. А чтобы тебе стало совсем понятно, что от этого никуда не деться, то многие разработчики указывают на то, что иногда нити просыпаются сами. Нити, которые гарантированно никто не может будить случайно. Похоже это побочный процесс оптимизации/ускорения кода в работающей Java-машине.

— Ничего себе. Понял, без цикла перед wait никуда.

Комментарии (30)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Максим Уровень 31 LA Украина
26 февраля 2021
Vladimir “Rain_Senpai1995” Soldatenko Уровень 35 Киев Украина
13 декабря 2020
Вообще ничего не понял.
Сиявуш Уровень 41 Худжанд Таджикистан Expert
6 февраля 2020
Теперь я понял зачем нужны эти материи! Оказывается когда у тебя время подписки закончился то ты можешь за материи прочить лекции. Но не можешь решить задачи. У меня сейчас закончился подписки и вот я читаю полезные лекции за счет материи пока не подключу подписку.
Wladyslaw Уровень 41 Украина Master
12 января 2020
А еще тред может быть разбужен сам по себе, в редких случаях. A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one: JavaDoc
Proficientoc Уровень 29 Киев Украина
2 ноября 2019
Классный стих!
Roman K Уровень 31 Петрозаводск Россия
31 августа 2019
Баю-баю, баю-бай только в цикле засыпай, все задачки ты решишь, злому Вале угодишь! Баю-баюшки-баю, я с Иф_элсами не сплю, придет серенький поток и разбудит мудачок. IDE сломает, C++ поставит. Баю-баю-баю-баю, ходишь ты дитя по краю, все Exception'ы лови, в блоке catch их выводи! Баю-баю, баю-бай, все ресурсы закрывай! Будет память целая, С ручками умелыми! Баю-баю, баю-бай, ты Амиго прокачай! уровень сороковой - Junior передовой! Баю-баю-бай-баю, на галере я гребу, скоро стану я лидом, буду смузи пить лаптём Это очень плохой код - повторяющийся код, строку эту "Баю-бай" сделай enum'ом давай! Или метод запили, вызывай на раз-два-три! Чтобы код был не пахучий, SOLID применяй могучий! Всё, устал я рифмовать, отправляюся я спать)
Александр Уровень 32 Россия
15 октября 2018
город засыпает... просыпаются нити...
Сергей Уровень 35 Одесса Украина
23 августа 2018
Баю-бай, баю-бай В if'е ты не засыпай Прийдет серенький Thread'чок И ухватит за бочок
Danila Уровень 39 Москва Россия
27 июля 2017
...иногда нити просыпаются сами O_O
Element 108 Уровень 36 Санкт-Петербург Россия
12 июля 2017
всё в этой Java-машине "на тоненького" :)