Tengo la clase principal de Java, en la clase, comienzo un nuevo hilo, en el principal, espera hasta que el hilo muere. En algún momento, lanzo una excepción de tiempo de ejecución desde el hilo, pero no puedo atrapar la excepción lanzada desde el hilo en la clase principal.
Aquí está el código:
public class Test extends Thread
{
public static void main(String[] args) throws InterruptedException
{
Test t = new Test();
try
{
t.start();
t.join();
}
catch(RuntimeException e)
{
System.out.println("** RuntimeException from main");
}
System.out.println("Main stoped");
}
@Override
public void run()
{
try
{
while(true)
{
System.out.println("** Started");
sleep(2000);
throw new RuntimeException("exception from thread");
}
}
catch (RuntimeException e)
{
System.out.println("** RuntimeException from thread");
throw e;
}
catch (InterruptedException e)
{
}
}
}
¿Alguien sabe por qué?
java
multithreading
NARU
fuente
fuente
Esto se debe a que las excepciones son locales a un hilo, y su hilo principal en realidad no ve el
run
método. Le sugiero que lea más sobre cómo funcionan los subprocesos, pero para resumir rápidamente: su llamado astart
iniciar un hilo diferente, totalmente ajeno a su hilo principal. La llamada ajoin
simplemente espera a que se haga. Una excepción que se lanza en un subproceso y nunca se captura lo termina, por lo quejoin
regresa a su subproceso principal, pero la excepción en sí se pierde.Si desea conocer estas excepciones no detectadas, puede intentar esto:
Puede encontrar más información sobre el manejo de excepciones no detectadas aquí .
fuente
Thread.setDefaultUncaughtExceptionHandler()
también se detectan excepciones en el hilo "principal"Esto explica la transición de estado de los subprocesos que dependen de si se produjeron excepciones o no:
Fuente: http://www-public.imtbs-tsp.eu/~gibson/Teaching/CSC7322/L8-ExceptionsAndThreads.pdf
fuente
Más probable;
Sin embargo, supongamos que necesita manejar una excepción de un subproceso hijo a otro. Usaría un ExecutorService como este:
huellas dactilares
fuente
future.get()
espera o bloquea hasta que el hilo ha finalizado la ejecución?Por favor, eche un vistazo a Thread.UncaughtExceptionHandler
La mejor manera (alternativa) es usar Callable y Future para obtener el mismo resultado ...
fuente
Use en
Callable
lugar de Thread, luego puede llamar, loFuture#get()
que arroja cualquier excepción que lanzó el Llamable.fuente
Callable.call
está envuelta en unaExcecutionException
y su causa tiene que ser evaluada.Actualmente solo está capturando
RuntimeException
, una subclase deException
. Pero su aplicación puede arrojar otras subclases de Excepción . Captura genéricaException
además deRuntimeException
Dado que muchas cosas se han cambiado en Threading front, use la API avanzada de Java.
Prefiere la API avanzada java.util.concurrent para subprocesos múltiples como
ExecutorService
oThreadPoolExecutor
.Puede personalizar su ThreadPoolExecutor para manejar excepciones.
Ejemplo de la página de documentación de Oracle:
Anular
Código de ejemplo:
Uso:
He agregado un constructor encima del código anterior como:
Puede cambiar este constructor para que se adapte a sus requisitos en cuanto al número de subprocesos.
fuente
Me enfrenté al mismo problema ... poca solución (solo para la implementación de objetos no anónimos) ... podemos declarar el objeto de excepción de nivel de clase como nulo ... luego inicializarlo dentro del bloque catch para el método de ejecución ... si hay fue un error en el método de ejecución, esta variable no será nula ... entonces podemos hacer una verificación nula para esta variable en particular y si no es nula, entonces hubo una excepción dentro de la ejecución del hilo.
llame a checkForException () después de unirse ()
fuente
¿Jugaste con setDefaultUncaughtExceptionHandler () y los métodos similares de la clase Thread? Desde la API: "Al configurar el controlador de excepción no capturado predeterminado, una aplicación puede cambiar la forma en que se manejan las excepciones no capturadas (como iniciar sesión en un dispositivo o archivo específico) para aquellos subprocesos que ya aceptarían cualquier comportamiento" predeterminado " sistema proporcionado ".
Puede encontrar la respuesta a su problema allí ... ¡buena suerte! :-)
fuente
También desde Java 8 puede escribir la respuesta de Dan Cruz como:
fuente
AtomicReference también es una solución para pasar el error al hilo principal. Es el mismo enfoque que el de Dan Cruz.
El único cambio es que, en lugar de crear una variable volátil, puede usar AtomicReference, que hizo lo mismo detrás de escena.
fuente
Casi siempre es incorrecto extender
Thread
. No puedo decir esto con suficiente fuerza.Regla de subprocesos múltiples # 1: Ampliar
Thread
es incorrecto. *Si implementa
Runnable
en su lugar, verá su comportamiento esperado.produce;
* a menos que desee cambiar la forma en que su aplicación usa subprocesos, que en el 99.9% de los casos no lo hace. Si cree que está en el 0.1% de los casos, consulte la regla n. ° 1.
fuente
Si implementa Thread.UncaughtExceptionHandler en la clase que inicia los subprocesos, puede establecer y volver a lanzar la excepción:
Lo que provoca el siguiente resultado:
fuente
Manejo de excepciones en Thread: por defecto, el método run () no arroja ninguna excepción, por lo que todas las excepciones marcadas dentro del método run deben capturarse y manejarse allí solo y para las excepciones de tiempo de ejecución podemos usar UncaughtExceptionHandler. UncaughtExceptionHandler es una interfaz proporcionada por Java para manejar excepciones en un método de ejecución Thread. Por lo tanto, podemos implementar esta interfaz y restablecer nuestra clase de implementación al objeto Thread utilizando el método setUncaughtExceptionHandler (). Pero este controlador debe configurarse antes de que llamemos a start () en la banda de rodadura.
si no establecemos uncaughtExceptionHandler, Threads ThreadGroup actúa como un controlador.
Buena explicación en http://coder2design.com/thread-creation/#exceptions
fuente
Mi solución con RxJava:
fuente
Para aquellos que necesitan detener la ejecución de todos los subprocesos y volver a ejecutarlos cuando alguno de ellos se detiene en una excepción:
Para resumir :
Tiene una función principal que crea múltiples subprocesos, cada uno de ellos tiene UncaughtExceptionHandler que se activa por cualquier excepción dentro de un subproceso. Agrega todos los hilos a una lista. Si se desencadena un UncaughtExceptionHandler, recorrerá la lista, detendrá cada subproceso y reiniciará la función principal que recrea todo el subproceso.
fuente
No puedes hacer esto, ya que realmente no tiene sentido. Si no hubiera llamado,
t.join()
entonces su hilo principal podría estar en cualquier parte del código cuando elt
hilo arroje una excepción.fuente