JavaRush /Курси /Java Multithreading /Стек викликів та перехоплення помилок

Стек викликів та перехоплення помилок

Java Multithreading
Рівень 5 , Лекція 8
Відкрита

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

Хочу розповісти тобі про маленьку, але цікаву річ.

— Я слухаю. Люблю цікаві та маленькі речі.

Так ось, ти знаєш, що кожен об'єкт Thread має метод run(). І що можна запустити його на виконання в окремій нитці за допомогою методу start().

— Так, звичайно.

— А ось уяви тепер ситуацію - ти запускаєш нитку, щоб вона виконала потрібну тобі роботу, а у неї всередині виникає Exception і вона завершує роботу, так і не виконавши того, що треба. Тобі треба якось дізнатися про цю помилку?

— Згоден. А що, якось можна перехопити виняток, який виник у іншій занедбаній нитці. Невже це навіть є в Java?

— Ображаєш. Ще як є.

Розробники Java придумали спеціальний інтерфейс UncaughtExceptionHandler. Ось як можна перехопити та обробити виняток в іншій нитці, якщо вона не перехопила його сама:

Приклад
public class DownloadManager
{
 public static void main(String[] args)
 {
   Thread thread = новий DownloadThread();
   thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { } });

thread.start();
}

Об'єкт типу Thread має спеціальний метод – setUncaughtExceptionHandler. В нього потрібно передати об'єкт, який реалізує інтерфейс Thread.UncaughtExceptionHandler. Цей інтерфейс має лише один метод uncaughtException(Thread t, Throwable e). Саме цей метод буде викликаний у переданого об'єкта, якщо всередині методу run виникне виняток, який не буде захоплено.

У наведеному прикладі, я просто оголошую анонімний внутрішній клас (виділено червоним), що реалізує інтерфейс Thread.UncaughtExceptionHandler. І перевизначаю в ньому метод uncaughtException(Thread t, Throwable e).

Як видно з параметрів методу, в нього будуть передані два параметри – посилання на Thread, у якому виник виняток, і сам виняток – Throwable e.

— А навіщо потрібне посилання на Thread — змінна t? Ми ж знаємо, який потік встановлюємо об'єкт типу Thread.UncaughtExceptionHandler?

— А це зроблено для того, щоб ти міг написати універсальний обробник таких ситуацій – створити єдиний об'єкт і передавати його десяткам різних потоків. Тоді всередині методу uncaughtException(Thread t, Throwable e) у тебе завжди буде посилання на нитку, де виник виняток.

Крім того, ти можеш створювати нитки десятками, наприклад, у циклі для виконання яких-небудь завдань. Загалом це посилання на нитку зайвої не буде, це я тобі обіцяю.

— Я тобі вірю. Ти ще жодного разу не помилялася.

Коментарі (2)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Olexandr Рівень 47
23 червня 2024
Ця лекція мала би бути раніше, коли була складна задача на обробник виключень в потоках...
23 серпня 2025
згоден! але напевно це такий задуманий підхід авторів) це дуже часто траплялось впродовж курсу.... спочатку якась незрозуміла задачка, а через пару рівнів слідує пояснення до цього в лекції)