В языке Java исключения делятся на две категории:
Проверяемое исключение. Исключение этого типа должно быть явно выброшено в предложении throws или перехвачено внутри метода. Например, IOException или ClassNotFoundException.
Непроверяемое исключение. Исключение этого типа не требуется явно вызывать или перехватывать. Например, NumberFormatException.
Когда проверенное исключение генерируется в методе run() объекта Thread, мы должны перехватить и обработать его, поскольку метод run() не может генерировать исключения. Когда в методе run() объекта Thread создается непроверенное исключение, поведение по умолчанию — распечатать информацию трассировки стека на консоли, а затем выйти из программы.
К счастью, Java предоставляет нам механизм, специально разработанный для обработки непроверенных исключений, создаваемых объектами Thread, чтобы избежать выхода из программы.
В этом разделе мы используем пример, чтобы продемонстрировать этот механизм.
знай это
Выполните шаги, показанные ниже, чтобы реализовать наш пример.
1. Во-первых, нам нужно реализовать класс для обработки непроверенных исключений. Этот класс должен реализовать класс UncaughtExceptionHandler и реализовать метод uncaughtException(), объявленный в этом интерфейсе. В этом примере имя класса — ExceptionHandler, а метод uncaughtException() выводит исключение и информацию о потоке, вызвавшем исключение. Код выглядит следующим образом:
Скопируйте код кода следующим образом:
публичный класс ExceptionHandler реализует Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException (Thread t, Throwable e) {
System.out.printf("Исключение было перехвачено//n");
System.out.printf("Тема: %s/n", t.getId());
System.out.printf("Исключение: %s: %s/n", e.getClass().getName(),
е.getMessage());
System.out.printf("Трассировка стека: /n");
e.printStackTrace(System.out);
System.out.printf("Состояние потока: %s/n", t.getState());
}
}
2. Реализовать класс, который может генерировать непроверяемые исключения, под названием Task, реализовать интерфейс Runnable, реализовать метод run() и специально закодировать фрагмент кода, который может генерировать непроверяемые исключения, например, преобразовывать строку в число. Код выглядит следующим образом:
Скопируйте код кода следующим образом:
Публичный класс Task реализует Runnable {
@Override
общественный недействительный запуск () {
int numero = Integer.parseInt("diguage.com");
}
}
3. Создайте основной класс программы — класс Main, а затем реализуйте метод main(). Код выглядит следующим образом:
Скопируйте код кода следующим образом:
общественный класс Main {
public static void main(String[] args) {
4. Создайте объект Task и создайте объект Thread для его выполнения. Используйте метод setUncaughtExceptionHandler(), чтобы установить класс обработки непроверенных исключений. Затем запустите ветку. Код выглядит следующим образом:
Скопируйте код кода следующим образом:
Задача задача = новая задача();
Поток потока = новый поток (задача);
thread.setUncaughtExceptionHandler(новый ExceptionHandler());
поток.start();
5. Запустите пример и просмотрите результаты.
знаю почему
Результат ненормального выполнения можно увидеть из фрагмента вывода ниже. Исключение генерируется, затем перехватывается классом-обработчиком, и информация об исключении выводится на консоль.
Скопируйте код кода следующим образом:
Исключение зафиксировано
Тема: 9
Исключение: java.lang.NumberFormatException: для входной строки: «diguage.com»
Трассировка стека:
java.lang.NumberFormatException: для входной строки: «diguage.com»
в java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
в java.lang.Integer.parseInt(Integer.java:492)
в java.lang.Integer.parseInt(Integer.java:527)
на com.diguage.books.concurrencycookbook.chapter1.recipe8.Task.run(Task.java:13)
в java.lang.Thread.run(Thread.java:722)
Статус темы: ВЫПОЛНЕНО
Процесс завершен с кодом выхода 0
Когда поток генерирует исключение и это исключение (здесь конкретно относится к непроверяемому исключению) не перехватывается, виртуальная машина Java проверяет, установлен ли класс обработки непроверяемого исключения с помощью соответствующего метода. Если он установлен, метод uncaughtException(). и передайте поток и исключение в качестве параметров методу.
Если класс обработки не установлен, виртуальная машина Java распечатает информацию трассировки стека на консоли, а затем выйдет из программы.
бесконечный
В классе Thread также есть метод, связанный с обработкой непроверенных исключений. Это статический метод setDefaultUncaughtExceptionHandler(), который может установить класс обработки непроверенных исключений для всех потоков в программе.
Когда в потоке создается неперехваченное исключение, виртуальная машина Java ищет классы обработки исключений в трех местах:
Сначала найдите класс обработки исключений в объекте потока, и это то, что мы узнали в этом разделе. Если он не существует, класс обработки исключений ищется в группе потоков (ThreadGroup), в которой находится поток. Эта часть будет подробно объяснена позже. Если он все еще не существует, найдите класс обработки исключений программы по умолчанию, упомянутый выше.
Если ни один из упомянутых выше обработчиков исключений не существует, виртуальная машина Java выводит информацию трассировки стека исключения на консоль, а затем выходит из программы.
Используйте доктрину
Эта статья переведена из «Книги по параллелизму Java 7» (Д Гуа Ге украл ее как «Коллекция примеров параллелизма Java7») и используется только в качестве учебных материалов. Его нельзя использовать в коммерческих целях без разрешения.
Небольшой успех
Полный код класса ExceptionHandler выглядит следующим образом:
пакет com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* Непроверенный класс обработки исключений.
* Дата: 22 сентября 2013 г.
* Время: 23:11
*/
публичный класс ExceptionHandler реализует Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException (Thread t, Throwable e) {
System.out.printf("Исключение было зафиксировано/n");
System.out.printf("Тема: %s/n", t.getId());
System.out.printf("Исключение: %s: %s/n", e.getClass().getName(),
е.getMessage());
System.out.printf("Трассировка стека: /n");
e.printStackTrace(System.out);
System.out.printf("Состояние потока: %s/n", t.getState());
}
}
Полный код класса Task
Скопируйте код кода следующим образом:
пакет com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* Класс генерации исключений
* Дата: 22 сентября 2013 г.
* Время: 23:18
*/
Публичный класс Task реализует Runnable {
@Override
общественный недействительный запуск () {
int numero = Integer.parseInt("diguage.com");
}
}
Полный код основного класса
Скопируйте код кода следующим образом:
пакет com.diguage.books.concurrencycookbook.chapter1.recipe8;
/**
* Основной класс примера
* Дата: 22 сентября 2013 г.
* Время: 23:20
*/
общественный класс Main {
public static void main(String[] args) {
Задача задача = новая задача();
Поток потока = новый поток (задача);
thread.setUncaughtExceptionHandler(новый ExceptionHandler());
поток.start();
}
}