Sobre Java
gestor de excepciones global, según una búsqueda en línea son SpringMVC
el manejador de excepción mundial. De hecho, el uso de Spring Boot
desarrollo o, para usar SSM
o lo que sea, se puede utilizar SpringMVC
un control de excepciones global, sino también el mejor, porque tenemos datos de las respuestas anormales a la parte delantera. Diciendo sobre SpringMVC
el manejo global de excepción, se conoce el principio de que? De hecho, se puede resumir en una frase, cualquier solicitud para ir a través DispatchServlet
.
Si la aplicación no es una SpringMVC
aplicación de la misma? Muchas personas pueden no saber, Java
y que han proporcionado gestor de excepciones global. Esto estaba de mi antigua dirección allí para escuchar. Pero esto no se aplica a un manejo global de excepción interfaz. Este artículo trata describe cómo utilizar Java
la oferta global de manejo de excepciones, y el análisis de punto hotspot
-fuente máquina virtual, la máquina virtual es para que todos sepan cómo procesador excepción mundial anormal.
excepción mundial manejador de demostración
En main
la configuración del método global de gestión de excepciones DefaultUncaughtExceptionHandler
, sino que también se puede ver desde el nombre, que se utiliza para procesar la excepción no detectada. No necesariamente desde main
el método de configuración, en spring
la aplicación, puede supervisar spring
el evento de finalización de inicialización, a continuación, establecer. (Si se trata de una aplicación web, o el uso SpringMVC
del gestor de excepciones global).
public static void main(String[] args) throws InterruptedException {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("这里是全局异常处理 ====> " + t.getId() + "==> "+e.getLocalizedMessage());
}
});
}
复制代码
Un amigo puede preguntarse, ¿por qué se fijó Thread
en su interior. A pesar de que se encuentra en el Thread
interior, pero esto es una variable estática.
Ya sabes, escribimos el código se ejecuta en una rosca interior. Un hilo corresponde a una Java
pila de la máquina virtual, es anormal (es decir, método) que se produce en el marco de pila. Cuando se produce una excepción llamando, una pila marco de pila, se produce una excepción de capas, y la información de pila de llamadas de escritura. A lo largo de la pila de llamadas, si usted no tiene manera de detectar la excepción, entonces la Java
máquina virtual desde el subproceso actual Thread
objeto de obtener un controlador de excepciones, en su caso, a la gestión de excepciones. Llegado hasta aquí, significa que el hilo está a punto de salir, este soy yo hotspot
en busca de penetración de código fuente.
Por supuesto, si el manejador de excepción se establece para un hilo, el hilo se encontró excepción no detectada, gestor de excepciones utilizará el conjunto de hilo, de lo contrario se utilizará el valor predeterminado global. Aquí no entendía que no importa, con más detalle su posterior análisis.
Seguimos el ejemplo de la lectura. En main
la creación de múltiples subprocesos de proceso y el hilo run
lanza un proceso de excepción.
private static class TaskThread extends Thread {
@Override
public void run() {
throw new NullPointerException("thread-" + Thread.currentThread().getId() + " Exception");
}
}
/**
* 在main方法中调用startThread(),
*/
public static void startThread(){
for (int i = 0; i < 10; i++) {
new TaskThread().start();
}
// 不让主线程退出
System.in.read();
}
复制代码
Resultado del programa:
这里是全局异常处理 ====> 13==> thread-13 Exception
这里是全局异常处理 ====> 16==> thread-16 Exception
这里是全局异常处理 ====> 15==> thread-15 Exception
........
复制代码
Como se mencionó anteriormente, también podemos configurar un manejador de excepción por separado para un hilo, y la prioridad será mayor que el valor predeterminado global. Si un controlador de excepciones para un solo hilo, a continuación, el hilo, el manejador de excepciones global predeterminada no funcionará. Vamos a modificar el ejemplo anterior startThread
método, verificar, el otro sin cambios.
/**
* 在main方法中调用startThread(),
*/
public static void startThread(){
for (int i = 0; i < 10; i++) {
Thread thread = new TaskThread();
if (i == 0) {
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("这是为当前线程设置的异步处理器。===> " + t.getId());
}
});
}
thread.start();
}
// 不让主线程退出
System.in.read();
}
复制代码
Los resultados de salida del programa son los siguientes:
这是为当前线程设置的异步处理器。===> 13
这里是全局异常处理 ====> 16==> thread-16 Exception
这里是全局异常处理 ====> 15==> thread-15 Exception
.......
复制代码
Obviamente, id
la igualdad 13
de gestión de excepciones hilo caminaba solo, mientras que otros hilos se han ido manejador de excepciones por omisión mundial. Un amigo puede ser curioso en cuanto a por qué un hilo id
desde el 13
principio, también se menciona en el artículo anterior, simplemente se olvidan lo que el artículo. id
Como 0
un mian
hilo, el hilo es entonces seguida por una máquina virtual, así como gc
hilo de recogida de basura porque mi equipo cpu
es una 9代i7
de seis núcleos doce hilos, el gc
número de hilos más. Digresión no tire demasiado.
En busca de respuestas desde el código fuente
Java
El gestor de excepciones global desde jdk1.5
inicio adición de nuevas características, no estoy seguro que no es 1.5
, comentarios de escritura. Mira debajo del gestor de excepciones UncaughtExceptionHandler
.
@FunctionalInterface
public interface UncaughtExceptionHandler {
/**
* 未捕获异常处理
*/
void uncaughtException(Thread t, Throwable e);
}
复制代码
Si en el uncaughtException
proceso, como un diario de registro de información diaria, los resultados, ya diario se producen IO
anormal, u otras anormalidades, no importa lo que es anormal, este método genera una excepción habría sido Java
máquina virtual ignorado, ya que el mensaje ha sido retirado a finales .
Thread
Se declara dos UncaughtExceptionHandler
tipos de variables, una variable estática. Que es variables no estáticas para la función de hilo actual, declarada volatile
razón es probable que las otras llamadas de rosca fijados; la otra es que el valor predeterminado global variables estáticas.
public class Thread implements Runnable {
// null unless explicitly set
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
// null unless explicitly set
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
}
复制代码
Estoy buscando en el código fuente cuando es a través del uso de la búsqueda local para ver cuál de los dos UncaughtExceptionHandler
, y finalmente dispatchUncaughtException
ver los comentarios en el método de la información crítica. Cuando se produce una excepción no capturada, java
la oportunidad virtual para llamar al hilo actual Thread
objeto dispatchUncaughtException
método.
/**
* Dispatch an uncaught exception to the handler. This method is
* intended to be called only by the JVM.
*/
private void dispatchUncaughtException(Throwable e) {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
复制代码
En el dispatchUncaughtException
método, llame al getUncaughtExceptionHandler
método para obtener UncaughtExceptionHandler
un objeto gestor de excepciones, a continuación, una excepción a la gestión de excepciones tiene que tratar.
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler != null ? uncaughtExceptionHandler : group;
}
复制代码
Aquí es muy extraño, y no utilizar defaultUncaughtExceptionHandler
las variables estáticas. Si el controlador de objetos hilo excepción actual no se establece, devuelve una group
. En primer lugar ver esto, podemos entender por qué la prioridad será utilizar un manejador de excepciones por ajustes del hilo.
Y group
de hecho ThreadGroup
el objeto. En Java
cada hilo tiene un grupo de hilos pertenece. Al llamar start
al método, el hilo actual se unirá a un grupo de hilos, y si se crea Thread
un objeto, ningún grupo de hilos de entrada ThreadGroup
, grupo de hilos obtendrá el hilo actual es probablemente el main
hilo pertenece al grupo de los hilos, no es que sea un poco alrededor, ellos mismos se ven muy buena fuente de entender.
public class ThreadGroup implements Thread.UncaughtExceptionHandler {
}
复制代码
ThreadGroup
Implementa UncaughtExceptionHandler
una interfaz, que tiene sentido, ¿por qué es un regreso group
, y luego buscar en ThreadGroup
el uncaughtException
método.
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
ueh.uncaughtException(t, e);
}
}
复制代码
grupo de hilos, así como el grupo de hilos de los padres, en torno a esto también, que la ignoran. Se puede ver, ThreadGroup
el uncaughtException
método se llama Thread.getDefaultUncaughtExceptionHandler();
método para obtener los ajustes por defecto del gestor de excepciones, esta es la configuración de nuestro gestor de excepciones global predeterminada.
De hecho, mirada cuidadosa a un código, se encuentra que ThreadGroup
el uncaughtException
comentario es 1.0
versión ha estado en existencia. Entonces miro hotspot
el código fuente y encontré compatible con las versiones anteriores, que Thread
el objeto no existe dispatchUncaughtException
cuando el método es poner en ThreadGroup
el uncaughtException
método.
A continuación nos fijamos en hotspot
el código fuente, y el aspecto hotspot
de cómo el gestor de llamadas excepción a manejar excepciones. No sé ver esto, si usted recuerda antes de decir una palabra, se invoca el manejador de excepciones, lo que indica que la corriente Java
no tiene un marco de pila en la máquina virtual pila para detectar la excepción, esto significa que el hilo actual está a punto de salir. Así, la fuente es la entrada de thread.cpp
clase exit
método. Ahora voy a ser la forma en que el código de la imagen publicada.
vm/runtime/thread.cpp
)
c++
El conocimiento que no va a decir. La figura en el cuadro rojo 0
, llama a la resolve_virtual_call
llamada a un método para obtener la información, es decir CallInfo
. Los parámetros se pasan CallInfo
un puntero (asignado c++
en la pila de rosca), el objeto del subproceso actual Thread
, el hilo Thread
de la Class
información de estructura de clase Klass
, dispatchUncaughtException
el nombre del método, firma del método.
Continuar para mirar thread.cpp
la exit
forma en que el cuadro rojo 1
es determinar Thread
si existe un dispatchUncaughtException
método en el que dijo a principios compatibles con versiones anteriores de. Si es así, entonces el hilo actual llama a la Thread
del objeto dispatchUncaughtException
métodos.
Si se trata jdk1.0
, entonces no tiene lugar cuadro de 1
código, pero se hizo muy popular cuadro 2
, obtener el hilo actual ThreadGroup
objeto, llamar a sus uncaughtException
métodos. Llamar call_virtual
método para ejecutar el java
código. Parámetro 1
es el Thread
objeto de parámetro 2
es el objeto de excepción.
Leer cuidadosamente el manual Creo que todos ya sabemos el Java
manejador de excepciones por defecto se invoca es como el. Por lo tanto, este estudio si podemos trabajar para conseguir, a continuación, busque en cada juego a.