J'ai écrit un fil de discussion, cela prend trop de temps à exécuter et il semble que ce ne soit pas complètement terminé. Je veux arrêter le fil gracieusement. De l'aide ?Comment faire pour arrêter un thread java gracieusement?
Répondre
La bonne façon de le faire est d'avoir le run()
du fil gardée par une variable boolean
et le mettre à true
de l'extérieur lorsque vous voulez arrêter, quelque chose comme:
class MyThread extends Thread
{
volatile boolean finished = false;
public void stopMe()
{
finished = true;
}
public void run()
{
while (!finished)
{
//do dirty work
}
}
}
Il était une fois une méthode stop()
existait mais comme les états de la documentation
Cette méthode est intrinsèquement dangereuse. L'arrêt d'un thread avec Thread.stop l'amène à déverrouiller tous les moniteurs qu'il a verrouillés (comme conséquence naturelle de l'exception ThreadDeath non cochée propageant la pile). Si l'un des objets précédemment protégés par ces moniteurs était dans un état incohérent, les objets endommagés deviennent visibles aux autres threads, ce qui peut entraîner un comportement arbitraire.
C'est pourquoi vous devriez avoir un garde ..
Créez un booléen volatil stop
quelque part. Ensuite, dans le code qui va dans le fil, faire régulièrement
if (stop) // end gracefully by breaking out of loop or whatever
Pour arrêter le fil, mettre stop
à true
.
Je pense que vous devez le faire manuellement de cette façon. Après tout, seul le code qui s'exécute dans le thread a une idée de ce qui est et n'est pas gracieux.
Notez que vous devez utiliser le verrouillage ou rendre le champ volatile pour vous assurer que le thread de lecture voit les modifications du thread d'écriture. –
@Jon Skeet: Oui, ce serait mieux. Par curiosité cependant, combien de temps l'arrêt serait-il retardé si le champ n'est pas volatil? –
@Bart: En pratique, probablement pas longtemps du tout. En théorie, pour toujours. –
Vous ne devriez pas tuer cette discussion d'autre. C'est considéré comme une mauvaise habitude. Cependant, il y a plusieurs façons. Vous pouvez utiliser l'instruction return
à partir de la méthode run
du thread. Ou vous pouvez vérifier si le fil a déjà été interrompu, puis il annulera son travail. F.e. :
while (!isInterrupted()) {
// doStuff
}
La méthode run est vide, elle ne peut rien retourner. –
vous pouvez utiliser l'instruction de retour vide avec le type de retour vide, la méthode se terminera – Xorty
cela est similaire à la première réponse, sauf que vous utilisez return au lieu de simplement laisser la méthode run() quitter. Et oui, vous pouvez simplement utiliser return; et cela va sortir d'une méthode vide – Richard
Vous devez envoyer un message d'arrêt au thread et le thread lui-même doit prendre des mesures si le message a été reçu. Ceci est assez facile, si l'action de longue durée est à l'intérieur boucle:
public class StoppableThread extends Thread {
private volatile boolean stop = false;
public void stopGracefully() {
stop = true;
}
public void run() {
boolean finished = false;
while (!stop && !finished) {
// long running action - finished will be true once work is done
}
}
}
Comme Jon Skeet a remarqué sur ma réponse, l'arrêt devrait être volatil –
J'ai édité ma réponse mais irai et découvrirai, pourquoi il s'applique ici - dans votre réponse, j'ai pensé, il devait être volatil juste parce que vous n'avez pas mentionné un méthode et il semblait que le champ 'stop' devait être accessible directement. –
Je me suis interrogé sur le mot-clé volatile avant et (sans essayer d'annoncer ma propre question :)), voici quelques réponses là-dessus: http://stackoverflow.com/questions/106591/do-you-ever- use-the-volatile-keyword-in-java – Richard
La mauvaise partie sur l'utilisation d'un drapeau pour arrêter votre fil est que si le fil est en attente ou dormir, alors vous devez attendre à finir d'attendre/dormir. Si vous appelez la méthode d'interruption sur le thread, cela provoquera l'arrêt de l'appel wait ou sleep avec une exception InterruptedException. L'appel à interruption() définit également une propriété interrompue que vous pouvez utiliser comme indicateur pour vérifier s'il faut quitter (dans le cas où le thread n'attend pas ou ne dort pas).
Vous pouvez écrire la méthode d'exécution du thread de sorte que l'exception InterruptedException soit interceptée en dehors de la logique de bouclage du thread ou vous pouvez intercepter l'exception dans la boucle et fermer l'appel en lançant l'exception. catch block pour l'exception InterruptedException afin que le thread ne perd pas de vue le fait qu'il a été interrompu. Le thread interrompu peut toujours garder le contrôle et terminer le traitement selon ses propres termes.Dites que je veux écrire un thread de travail qui fonctionne par incréments, où il y a un sommeil au milieu pour une raison quelconque, et je ne veux pas quitter le sommeil pour arrêter le traitement sans faire le travail restant pour cet incrément , je veux seulement à quitter si elle est en entre les incréments:
class MyThread extends Thread
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
doFirstPartOfIncrement();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// restore interrupt flag
Thread.currentThread().interrupt();
}
doSecondPartOfIncrement();
}
}
}
Here is an answer to a similar question, including example code.
pour un fil pour s'arrêter, personne ne semble avoir mentionné (mis) en utilisant exception:
abstract class SelfStoppingThread extends Thread {
@Override
public final void run() {
try {
doRun();
} catch (final Stop stop) {
//optional logging
}
}
abstract void doRun();
protected final void stopSelf() {
throw new Stop();
}
private static final class Stop extends RuntimeException {};
}
Une sous-classe a juste besoin de surcharger doRun() normalement comme vous le feriez avec un Thread, et d'appeler stopSelf() chaque fois qu'elle a envie de s'arrêter. IMO est plus propre que d'utiliser un drapeau dans une boucle while.
- 1. Arrêter gracieusement NSXMLParser?
- 2. java: Comment arrêter un thread qui attend de longues périodes
- 3. java comment faire un thread d'expéditeur
- 4. Comment arrêter un NSThread sous-thread iphone
- 5. Comment récupérer gracieusement à partir de TargetInvocationException dans multi thread?
- 6. Jython Comment arrêter le script d'un thread?
- 7. Comment supprimer un thread d'un autre thread dans Java?
- 8. Arrêter la transaction dans un thread
- 9. Comment faire pour que TcpClient s'arrête dans un thread?
- 10. Shell script pour arrêter un programme java
- 11. Comment faire pour arrêter Wscript Exe
- 12. Java Executors: comment arrêter les tâches soumises?
- 13. Comment arrêter un thread lorsque la fenêtre se ferme et
- 14. Comment arrêter les threads en Java?
- 15. Comment faire pour Java Midi STOP
- 16. Comment arrêter un thread, autoriser le traitement d'un événement d'interface utilisateur, puis "redémarrer" le thread?
- 17. Comment faire pour dormir un thread Boost C++
- 18. Comment terminer un thread dans Java?
- 19. Synchronisé dans un thread Java
- 20. Comment arrêter le thread asynchrone après 5 secondes de fonctionnement
- 21. Comment faire pour que le thread en cours d'attente pour une fonction à retourner dans Java?
- 22. Java: comment faire que ce thread principal attende la fin du nouveau thread
- 23. Java: thread-safe RandomAccessFile
- 24. Comment faire pour arrêter le script batch sur l'échec
- 25. Comment faire pour arrêter .Net HttpWebRequest.GetResponse() déclencher une exception
- 26. jQuery: Comment faire pour arrêter le mouvement du ticker
- 27. Comment faire pour arrêter ComboBox SelectionChange de l'événement SelectionChanged
- 28. Comment faire pour arrêter l'application et exécuter le débogueur?
- 29. Comment faire pour arrêter l'exécution du programme Python dans IDLE
- 30. Comment faire pour arrêter les URLs de désenchaînement XSL
Voir le commentaire de Jon Skeet à la réponse de Bart - il s'applique également à la vôtre. –
Si "fini" change pendant que vous faites votre "sale boulot" le fil ne se termine pas, alors vous devez faire une vérification périodique, par exemple avec un sommeil (x) dans la boucle, quelque chose qui n'est pas recommandé et vous donne une mauvaise performance, alors est-ce vraiment une bonne approche? –
nous parlons de quitter un fil gracieusement. Forcer un thread à quitter au milieu de son sale boulot n'est pas une façon élégante de le faire. Vous devriez toujours attendre la prochaine itération sauf si vous avez une raison spécifique de l'interrompre. – Jack