J'ai la classe principale Java, dans la classe, je démarre un nouveau thread, dans l'ensemble, il attend que le thread meure. À un moment donné, je lance une exception d'exécution à partir du thread, mais je ne peux pas attraper l'exception lancée à partir du thread dans la classe principale.
Voici le code:
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)
{
}
}
}
Quelqu'un sait pourquoi?
java
multithreading
NARU
la source
la source
C'est parce que les exceptions sont locales à un thread et que votre thread principal ne voit pas réellement la
run
méthode. Je vous suggère de lire plus sur le fonctionnement du threading, mais pour résumer rapidement: votre appel àstart
démarrer un thread différent, totalement indépendant de votre thread principal. L'appel àjoin
attend simplement qu'il soit fait. Une exception qui est levée dans un thread et qui n'est jamais interceptée le termine, c'est pourquoijoin
revient sur votre thread principal, mais l'exception elle-même est perdue.Si vous voulez être conscient de ces exceptions non interceptées, vous pouvez essayer ceci:
Vous trouverez plus d'informations sur la gestion des exceptions non interceptées ici .
la source
Thread.setDefaultUncaughtExceptionHandler()
également les exceptions dans le thread "main"Cela explique la transition d'état des threads selon que des exceptions se sont produites ou non:
Source: http://www-public.imtbs-tsp.eu/~gibson/Teaching/CSC7322/L8-ExceptionsAndThreads.pdf
la source
Probablement;
Cependant, supposons que vous ayez besoin de gérer une exception d'un thread enfant à un autre. J'utiliserais un ExecutorService comme celui-ci:
impressions
la source
future.get()
ou ne bloque pas jusqu'à ce que l'exécution du thread soit terminée?Veuillez jeter un œil à Thread.UncaughtExceptionHandler
Le meilleur moyen (alternatif) est d'utiliser Callable et Future pour obtenir le même résultat ...
la source
Utilisez à la
Callable
place de Thread, vous pouvez alors appelerFuture#get()
qui lève toute exception levée par Callable.la source
Callable.call
est encapsulée dans unExcecutionException
et sa cause doit être évaluée.Actuellement, vous capturez uniquement
RuntimeException
, une sous-classe deException
. Mais votre application peut lancer d'autres sous-classes d' Exception . Catch génériqueException
en plus deRuntimeException
Étant donné que de nombreuses choses ont été modifiées sur le front du thread, utilisez l'API Java avancée.
Préférez avance java.util.concurrent API pour le multi-threading comme
ExecutorService
ouThreadPoolExecutor
.Vous pouvez personnaliser votre ThreadPoolExecutor pour gérer les exceptions.
Exemple de la page de documentation d'Oracle:
Passer outre
Exemple de code:
Usage:
J'ai ajouté un constructeur au-dessus du code ci-dessus comme:
Vous pouvez modifier ce constructeur en fonction de vos besoins en termes de nombre de threads.
la source
J'ai rencontré le même problème ... peu de travail (uniquement pour l'implémentation et non les objets anonymes) ... nous pouvons déclarer l'objet d'exception au niveau de la classe comme nul ... puis l'initialiser dans le bloc catch pour la méthode d'exécution ... s'il y a était une erreur dans la méthode d'exécution, cette variable ne sera pas nulle .. nous pouvons alors avoir une vérification nulle pour cette variable particulière et si ce n'est pas nul, alors il y a eu une exception dans l'exécution du thread.
appeler checkForException () après join ()
la source
Avez-vous joué avec setDefaultUncaughtExceptionHandler () et les méthodes similaires de la classe Thread? Depuis l'API: "En définissant le gestionnaire d'exceptions non interceptées par défaut, une application peut modifier la manière dont les exceptions non interceptées sont gérées (comme la journalisation vers un périphérique ou un fichier spécifique) pour les threads qui accepteraient déjà le comportement" par défaut "du système fourni. "
Vous y trouverez peut-être la réponse à votre problème ... bonne chance! :-)
la source
Aussi à partir de Java 8, vous pouvez écrire la réponse de Dan Cruz comme suit:
la source
AtomicReference est aussi une solution pour passer l'erreur au thread principal. C'est la même approche que celle de Dan Cruz.
Le seul changement est qu'au lieu de créer une variable volatile, vous pouvez utiliser AtomicReference qui a fait la même chose dans les coulisses.
la source
Il est presque toujours faux de prolonger
Thread
. Je ne peux pas le dire assez clairement.Règle de multithreading n ° 1: l'extension
Thread
est incorrecte. *Si vous implémentez à la
Runnable
place, vous verrez votre comportement attendu.produit;
* sauf si vous souhaitez modifier la façon dont votre application utilise les threads, ce qui n'est pas le cas dans 99,9% des cas. Si vous pensez être dans les 0,1% des cas, veuillez consulter la règle n ° 1.
la source
Si vous implémentez Thread.UncaughtExceptionHandler dans la classe qui démarre les threads, vous pouvez définir puis renvoyer l'exception:
Ce qui provoque la sortie suivante:
la source
Gestion des exceptions dans Thread: Par défaut, la méthode run () ne lève aucune exception, donc toutes les exceptions vérifiées à l'intérieur de la méthode run doivent être interceptées et traitées uniquement et pour les exceptions d'exécution, nous pouvons utiliser UncaughtExceptionHandler. UncaughtExceptionHandler est une interface fournie par Java pour gérer les exceptions dans une méthode d'exécution Thread. Nous pouvons donc implémenter cette interface et redéfinir notre classe d'implémentation sur l'objet Thread en utilisant la méthode setUncaughtExceptionHandler (). Mais ce gestionnaire doit être défini avant d'appeler start () sur la bande de roulement.
si nous ne définissons pas uncaughtExceptionHandler, le Threads ThreadGroup agit comme un gestionnaire.
Belle explication donnée sur http://coder2design.com/thread-creation/#exceptions
la source
Ma solution avec RxJava:
la source
Pour ceux qui doivent arrêter tous les threads en cours d'exécution et les réexécuter tous lorsque l'un d'entre eux est arrêté sur une exception:
Pour résumer :
Vous avez une fonction principale qui crée plusieurs threads, chacun d'eux a UncaughtExceptionHandler qui est déclenché par n'importe quelle exception à l'intérieur d'un thread. Vous ajoutez chaque fil à une liste. Si un UncaughtExceptionHandler est déclenché, il boucle à travers la liste, arrête chaque thread et relance la fonction principale recréant tout le thread.
la source
Vous ne pouvez pas faire cela, car cela n'a pas vraiment de sens. Si vous n'avez pas appelé,
t.join()
votre thread principal pourrait se trouver n'importe où dans le code lorsque let
thread lève une exception.la source