Fil de Java: la méthode ne peut pas jeter vérifié exception
Dans le fil de Java, la méthode ne peut pas lancer un " checked exception. Je suis tombé sur ceci dans le Noyau de Java (vol 1) livre. Quelqu'un peut-il expliquer le raisonnement derrière cela?
Où serait l'exception aller? Le thread qui a donné naissance à la nouvelle thread a depuis changé. Alors, comment le nouveau thread "envoyer" à l'exception de la création de thread qui avait tiré et oublié dit thread?
OriginalL'auteur Neel | 2010-12-20
Vous devez vous connecter pour publier un commentaire.
Oui, parce que toute exception vous lancer dans des
run
méthode sera soigneusement ignoré par la JVM. Ainsi, de le jeter il y a probablement une erreur (sauf si vous avez spécifiques gestionnaire d'exception pour le thread, voir les docs à ce sujet). Pas de raison de les inciter potentiellement erronées comportement.Ou, avec un exemple.
modifier
@chaotic3quilibrium l'a déjà fait remarquer dans son commentaire pourquoi: parce que les parents thread a probablement déplacé sur déjà.
run
?Quoi d'autre peut-il faire? Le Suicide de l'option sons encore pire: vous ne voudriez pas que l'ensemble de l'application à bloquer en raison d'un thread.
Silenty ignorer, c'est peut-être trompeuse. L'exception sera traitée par le thread UncaughtExceptionHandler, le défaut de mise en œuvre de ce qui provoque le vidage de la stacktrace de Système.err avant de tuer le thread. Quant à savoir pourquoi: Comment la VM savoir quoi faire à la place?
Eh bien, je pourrais. Comment osez la JVM décider quels sujets sont essentiels et qui ne le sont pas? Citant Eric Lippert sur le CLR "vous auriez du commencer un tas de threads de travail, ils avaient tous lancer des exceptions, et que vous souhaitez retrouver avec une application en cours d'exécution avec aucun threads gauche, faire aucun travail, et de ne pas dire à l'utilisateur. Il est préférable de force de l'auteur du code pour gérer la situation où un travailleur fil va vers le bas en raison d'une exception; le faire à l'ancienne masque efficacement les bugs et rend plus facile l'écriture fragiles demandes."
Pourquoi ne peut pas le parent thread "attraper" l'exception de l'a engendré "enfant" thread? Après tout, la JVM sait qu'il est le parent thread est vraiment intéressé au sujet de l'exception?
OriginalL'auteur Nikita Rybak
Ce serait attraper l'exception et le gérer? Supposons que la méthode run pourrait jeter un checked exception. Ensuite, vous pouvez écrire du code comme ceci:
MAIS une fois que vous appelez
myThread.start
, le nouveau thread est lancé en arrière-plan et le thread courant continue et quitte le try-catch et fait d'autres choses. Donc, simyThread
fait lever une exception plus tard, vous ne pouvez pas l'attraper!Ce que vous devez faire est de traiter l'exception au sein de la
run
méthode, puis probablement une façon de prévenir un autre objet que ce fil a échoué.OriginalL'auteur dogbane
Supposons qu'Un thread démarre le thread B. thread B déclenche une exception. Vous pensez qu'il serait sympa pour passer le fil de l'attraper. Mais où? Par les temps thread B thows l'exception, qui sait ce qu'Un thread est en train de faire? Pour prendre un exemple trivial, supposons que nous avons ce code dans Un thread:
Donc, nous partons du fil B pour purger les paniers abandonnés. Une fois qu'il est starte, nous nous déplaçons sur le traitement de nouvelles commandes. Thread B lance une exception de pointeur null. Devrait-il être attrapé par le bloc catch associés avec le fil B, ou celui qui est associé avec le traitement de nouvelles commandes?
Si il va à nouveau les commandes de capture, il est probable que le code ici n'a rien à voir avec le nettoyage de problèmes avec le fil B. Qui ne peut pas être la bonne réponse.
Si vous dites que celui qui est associé avec le fil B, alors cela signifie que pendant le processus de traitement de commandes, le contrôle pourrait être soudainement arrachés et envoyé en arrière pour essayer de thread B bloc catch. Mais alors qu'est-happenned pour le traitement de nouvelles commandes? - Nous tout simplement arrêter dans le milieu? N'avons-nous pas encore touché le bloc finally? Et quand nous aurons terminé, nous ne puis juste continuer à l'exécution et à l'automne à travers le traitement des nouvelles commandes à nouveau? Ne nous traitons les commandes deux fois? Cela ne peut pas être la bonne réponse.
Ainsi, il n'y a nulle part où aller si vous exécutez déclenche une exception. La seule chose logique à faire est d'avoir de la méthode run attraper toutes les exceptions levées lui-même, et de les gérer dans le nouveau thread.
OriginalL'auteur Jay
throws
déclarations font partie des méthodes de signature. Pour permettre checked exceptions pourRunnable#run
, il fallait les déclarer sur laRunnable
interface et a dûtry/catch
chaque fois que nous commençons à un fil.Puis de nouveau, nous avons l'habitude de ne pas appeler le
run
méthode, nous venons de la mettre en œuvre. Nousstart()
un Fil et puis, en quelque sorte, lerun
méthode est appelée.Mais la raison la plus évidente: Quand on commence threads, nous avons l'habitude ne voulez pas attendre jusqu'à ce que le
run
méthode se termine juste à intercepter des exceptions comme ceci:OriginalL'auteur Andreas_D
La raison en est que l'exception est renvoyée à l'appelant. Appelant de la méthode run() n'est pas de votre code. C'est le Thred lui-même. Donc, même si le run() throws exception, le programme ne peut pas l'attraper.
Vous devriez mettre de l'exécution du thread résultat à une classe de niveau variable, puis le lire à partir de là. Ou vous pouvez également utiliser la nouvelle API: exécuteurs testamentaires et interface Appelable qui déclare la méthode call() qui retourne futures résultat de l'exécution du thread.
OriginalL'auteur AlexR
La plus solution la plus évidente pour les réponses précédentes, c'est que si vous jetez un checked exception, vous n'êtes pas correctement mise en œuvre de run() tel que spécifié dans l'interface runnable.
Il ne sera même pas compiler:
OriginalL'auteur Benjamin Wootton