UncaughtExceptionHandler
O método run do thread não pode lançar nenhuma exceção verificada, mas exceções não verificadas podem fazer com que o thread seja encerrado. Nesse caso, o thread morrerá, o que também fará com que o thread principal seja encerrado de forma anormal.。
Para exceções que podem ser propagadas, a exceção é passada para um manipulador de exceções não detectadas antes que o encadeamento seja encerrado. A premissa é que o processador deve ser uma classe que implementa Thread.UncaughtExceptionHandler
a interface。
O que essas palavras significam? Continue lendo.
Da seguinte forma, se eu forçosamente lançar uma exceção no método run, um erro será relatado.
![imagem-20201218225951286](https://img-blog.csdnimg.cn/20201224232833483.png)
Portanto, quando uma exceção é encontrada no thread, try-catch
só podemos capturar a exceção o máximo possível.
![imagem-20201218225951286](https://img-blog.csdnimg.cn/20201224233447113.png)
Mas no método run de cada thread, é impossível agrupar cada frase do código em um grande try-catch
bloco de código. As exceções verificadas devem ser agrupadas com blocos de código try-catch, mas também existem muitas exceções não verificadastry-catch
. Não podemos garantir que as exceções não verificadas não darão errado, mas não é apropriado agrupar todas as exceções não verificadas .
Por favor veja o código abaixo.
O primeiro pedaço de código:
package concurrence;
public class UncaughtExceptionHandlerTest {
public static void main(String[] args) throws InterruptedException {
try {
Thread thread1 = new Thread(new MyRunnable());
thread1.start();
} catch (Exception ex) {
System.out.println("Exception:" + ex.getMessage());
}
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println(2 / 1);
System.out.println(2 / 0);
System.out.println(2 / 2);
}
}
No método run do thread1, há um 2/0
erro, que é ArithmeticException
uma exceção. Essa é uma exceção não verificada, por isso não try-catch
a envolvemos com um bloco de código. Mas uma vez que o código lança uma exceção não verificada , não podemos capturá-la em outros threads. Portanto, embora eu tenha tentado capturar exceções não verificadas no thread principal , não consegui capturá-las e, eventualmente, o programa teve que ser encerrado devido a exceções.
Normalmente, veja:
O segundo pedaço de código:
package concurrence;
public class Test {
public static void main(String[] args) {
try {
dividByZero();
} catch (Exception ex) {
System.out.println("Exception:" + ex);
}
}
public static void dividByZero() {
System.out.println(2 / 1);
System.out.println(2 / 0);
System.out.println(2 / 2);
}
}
Em circunstâncias normais, podemos capturar exceções não verificadas para que nosso programa não seja encerrado devido a exceções.
Mas agora, em multithreading, não podemos pegar exceção não verificada no método run . Isso significa que, se não detectarmos a exceção não verificada com um bloco de código run
no método , o programa será encerrado por causa da exceção?try- catch
Claro que não, neste momento você pode fazer UncaughtExceptionHandler
sua estreia.
Para exceções que podem ser propagadas, a exceção é passada para um manipulador de exceções não detectadas antes que o encadeamento seja encerrado. A premissa é que o processador deve ser uma classe que implementa Thread.UncaughtExceptionHandler
a interface.
Então, MyUncaughtExceptionHandler
reescrevi o método na classe Thread.UncaughtExceptionHandler
e uncaughtException
defini o tratamento de exceções neste método. Então thread1
start
, antes, use setUncaughtExceptionHandler
o método para definir o segmento.
O terceiro pedaço de código:
package concurrence;
public class UncaughtExceptionHandlerTest {
public static void main(String[] args) throws InterruptedException {
try {
Thread thread1 = new Thread(new MyRunnable());
thread1.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
thread1.start();
} catch (Exception ex) {
System.out.println("Exception:" + ex.getMessage());
}
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println(2 / 1);
System.out.println(2 / 0);
System.out.println(2 / 2);
}
}
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + " " + e.getMessage());
}
}
Dessa forma, quando ocorrer uma exceção não verificada no método run , antes da morte do thread1, podemos capturar a exceção no thread principal, para que o programa principal também termine normalmente e não seja encerrado por causa da exceção .
Reimpresso: https://blog.csdn.net/qq_42799615/article/details/111658473