Java. Multithreading. Wait and Notify methods. Blocking Queue and Worker Thread.
Vložit
- čas přidán 21. 08. 2024
- Previous video: • Java. Многопоточность....
In this video we continue studying elementary multithreading in Java. It's shown how the wait and notify methods work. How to use them to build a blocking queue. How to create a Worker Thread based on the queue.
Вау. Это талант. Вы объяснили за 16 минут (+прошлое видео) то, что я не смог понять читая различные статьи несколько часов.
Прекрасний приклад і подача матеріалу. Дякую за корисне відео
на 2:22 неточность. Нить, вызывая метод wait, НЕ блокируется(нить переходит в состояние BLOCKED), а ОЖИДАЕТ(нить переходит в состояние WAITING). После того как другая нить вызовет метод notify, ожидающая нить перейдет в состояние RUNNABLE и попытается захватить монитор. В случае если монитор успела захватить другая нить, то наша нить заблокируется(состояние BLOCKED)
Да, все так, спасибо за уточнение.
Не уроки, а песня прямо какая-то))
Спасибо за ваш труд!
Спасибо большое! Повторение - мать учения!
Очень интересный пример! Спасибо!
Отлично объясняешь! Спокойно, просто и понятно. Еще бы рассказал про отличие notify() от notifyAll()
Спасибо, брат. Супер полезные видосы. Удачи в прокачке канала.
Спасибо, Сергей. Супер.
Спасибо, теперь мне понятнее как устроен handlerThread и его очередь)
Спасибо вам, сенсеэй!
Супер. так просто о сложном
Отличное видео! Буду знать альтернативу. Даже не задумывался об этом. По дефолту threadpoolexecutor для этих целей всегда юзал) Теперь буду знать альтернативу на один поток) Спасибо!
Это не совсем альтернатива. По смыслу это тот же executor, только написанный вручную. И потоков можно ещё добавить, если надо. В общем, если бы не было executor, то можно было бы его так реализовать.
@@arhitutorials до Ваших видео я думал я хоть немного в Java понимаю. Сейчас вижу что еще расти и расти. Я и раньше так думал, но сейчас вижу, что пропасть еще больше)
remove(index) елемента коллекции возвращает удалённый элемент))
Спасибо! Очень доступно и в то же время без воды🔥 Не плохо было бы добавить кнопочку "спонсировать"...
Один вопрос: я так понимаю здесь реализован producer - consumer. Всегда ли будет выполняться порядок добавлено-взято...добавлено-взято или могут быть ситуации, когда сначало будет несколько раз подряд добавлено, а потом несколько раз взято?
Я правильно понимаю, что если для worker установить setDaemon(true), то main завершит свою работу после того как задачи закончатся?
Нет, нить (Thread) закончит работу, когда все основные потоки (не daemon) закончат свою работу. В данном случае когда поток main закончит работу, а это сразу после добавления заданий в Array
Я не могу сообразить, а когда происходит выполнение метода start()?
Thread t1 = new Thread(printA());
Thread t2 = new Thread(printB());
Thread t3 = new Thread(printC());
for (int i = 0; i < 5; i++) {
queue.put(t1);
queue.put(t2);
queue.put(t3);
}
Спасибо Сергей за Ваши уроки!
Метод thread.start() стартует выполнение потока. Мы может создать поток так:
Thread t = new Thread(() -> {
...код, который будет исполняться потоком...
})
При этом поток создается, но он еще не запущен и ничего не выполняет.
если вызвать у него метод
t.start()
то поток t запускается, выполнение кода внутри потока начинается немедленно, а поток, который вызвал t.start() продолжает дальше по коду заниматься своими делами.
Короче говоря, поток надо создать, а потом еще запустить методом start(), чтоб он что-то делал.
@@arhitutorials Спасибо за ответ. Если позволите я задам ещё вопрос. У меня три потока которые печатают каждый свою букву. А ЧТО происходит когда я эти потоки помещаю в класс очереди, в цикле? Потоки работаю синхронизированно или просто последовательно вызывается метод run? В консоли как будто синронизированно.
@@maniana1987 Thread имплементирует интерфейс Runnable, по этому когда потоки добавляются в очередь, у них просто вызывается метод run() как у обычного Runnable, что к запуску потока не приводит, а приводит лишь к исполнению Runnable, который передан в конструктор потока при создании.
То есть потоки в коде выше как потоки не используются вообще. А просто поток, обслуживающий очередь последовательно выполнит printA, printB, printC.
Если после wait блокировка снята, то получается что доступ к tasks становится не защищенным с точки зрения многопоточности?
Очень хороший вопрос. Если поток остановился на wait, а потом другой поток вызвал notify, то поток возвращается в активное состояние. Но, мы помним, что внутри synchronized блоков может работать только один поток, удерживающий в данный момент монитор. Монитор будет у потока, который вызвал notify. По этому хоть поток, который спал на wait, и разбужен, он не может сразу начать выполнять код следующий за wait, а будет вынужден ждать, пока другой поток освободит монитор.
То есть, все правила, касающиеся syncronized блоков выполняются, нарушения потокобезопасности нет.
Можно себе представить, что вызывая метод wait, поток выходит из syncronized блока отпуская монитор и после notify, вынужден в него возвращаться по всем правилам работы syncronized блоков.
Ааааа, как обидно, когда нихера не понял как это работает.
Не стоит переживать, тема сложная, я сам когда это изучал, с первого раза не понял и со второго тоже) Так что это нормально. Надо вернуться позже к этому вопросу и снова попробовать разобраться, если будет интерес.