Java manejador global de excepción, no se sabe operaciones Sao punto de acceso (incluyendo análisis de código fuente)

Sobre Javagestor de excepciones global, según una búsqueda en línea son SpringMVCel manejador de excepción mundial. De hecho, el uso de Spring Bootdesarrollo o, para usar SSMo lo que sea, se puede utilizar SpringMVCun control de excepciones global, sino también el mejor, porque tenemos datos de las respuestas anormales a la parte delantera. Diciendo sobre SpringMVCel 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 SpringMVCaplicación de la misma? Muchas personas pueden no saber, Javay 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 Javala 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 mainla 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 mainel método de configuración, en springla aplicación, puede supervisar springel evento de finalización de inicialización, a continuación, establecer. (Si se trata de una aplicación web, o el uso SpringMVCdel 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ó Threaden su interior. A pesar de que se encuentra en el Threadinterior, pero esto es una variable estática.

Ya sabes, escribimos el código se ejecuta en una rosca interior. Un hilo corresponde a una Javapila 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 Javamáquina virtual desde el subproceso actual Threadobjeto 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 hotspoten 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 mainla creación de múltiples subprocesos de proceso y el hilo runlanza 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 startThreadmé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, idla igualdad 13de 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 iddesde el 13principio, también se menciona en el artículo anterior, simplemente se olvidan lo que el artículo. idComo 0un mianhilo, el hilo es entonces seguida por una máquina virtual, así como gchilo de recogida de basura porque mi equipo cpues una 9代i7de seis núcleos doce hilos, el gcnúmero de hilos más. Digresión no tire demasiado.

En busca de respuestas desde el código fuente

JavaEl gestor de excepciones global desde jdk1.5inicio 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 uncaughtExceptionproceso, como un diario de registro de información diaria, los resultados, ya diario se producen IOanormal, u otras anormalidades, no importa lo que es anormal, este método genera una excepción habría sido Javamáquina virtual ignorado, ya que el mensaje ha sido retirado a finales .

ThreadSe declara dos UncaughtExceptionHandlertipos de variables, una variable estática. Que es variables no estáticas para la función de hilo actual, declarada volatilerazó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 dispatchUncaughtExceptionver los comentarios en el método de la información crítica. Cuando se produce una excepción no capturada, javala oportunidad virtual para llamar al hilo actual Threadobjeto dispatchUncaughtExceptionmé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 dispatchUncaughtExceptionmétodo, llame al getUncaughtExceptionHandlermétodo para obtener UncaughtExceptionHandlerun 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 defaultUncaughtExceptionHandlerlas 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 groupde hecho ThreadGroupel objeto. En Javacada hilo tiene un grupo de hilos pertenece. Al llamar startal método, el hilo actual se unirá a un grupo de hilos, y si se crea Threadun objeto, ningún grupo de hilos de entrada ThreadGroup, grupo de hilos obtendrá el hilo actual es probablemente el mainhilo 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 {
}
复制代码

ThreadGroupImplementa UncaughtExceptionHandleruna interfaz, que tiene sentido, ¿por qué es un regreso group, y luego buscar en ThreadGroupel uncaughtExceptionmé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, ThreadGroupel uncaughtExceptionmé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 ThreadGroupel uncaughtExceptioncomentario es 1.0versión ha estado en existencia. Entonces miro hotspotel código fuente y encontré compatible con las versiones anteriores, que Threadel objeto no existe dispatchUncaughtExceptioncuando el método es poner en ThreadGroupel uncaughtExceptionmétodo.

A continuación nos fijamos en hotspotel código fuente, y el aspecto hotspotde 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 Javano 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.cppclase exitmétodo. Ahora voy a ser la forma en que el código de la imagen publicada.

(Cuando el archivo de origen: vm/runtime/thread.cpp )

c++El conocimiento que no va a decir. La figura en el cuadro rojo 0, llama a la resolve_virtual_callllamada a un método para obtener la información, es decir CallInfo. Los parámetros se pasan CallInfoun puntero (asignado c++en la pila de rosca), el objeto del subproceso actual Thread, el hilo Threadde la Classinformación de estructura de clase Klass, dispatchUncaughtExceptionel nombre del método, firma del método.

Continuar para mirar thread.cppla exitforma en que el cuadro rojo 1es determinar Threadsi existe un dispatchUncaughtExceptionmétodo en el que dijo a principios compatibles con versiones anteriores de. Si es así, entonces el hilo actual llama a la Threaddel objeto dispatchUncaughtExceptionmétodos.

Si se trata jdk1.0, entonces no tiene lugar cuadro de 1código, pero se hizo muy popular cuadro 2, obtener el hilo actual ThreadGroupobjeto, llamar a sus uncaughtExceptionmétodos. Llamar call_virtualmétodo para ejecutar el javacódigo. Parámetro 1es el Threadobjeto de parámetro 2es el objeto de excepción.

Leer cuidadosamente el manual Creo que todos ya sabemos el Javamanejador 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.

Supongo que te gusta

Origin juejin.im/post/5e662d246fb9a07cb427e538
Recomendado
Clasificación