69 votes

Comment arrêter un fil de java avec élégance?

J'ai écrit un fil, cela prend trop de temps à exécuter et il semble que ce ne soit pas complètement terminé. Je veux arrêter le fil avec grâce. De l'aide ?

70voto

Jack Points 61503

La bonne façon de le faire est d'avoir l' run() de la Thread gardé par un boolean variable et réglez - true de l'extérieur lorsque vous voulez l'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
    }
  }
}

Une fois un stop() méthode existé, mais que les états de documentation

Cette méthode est dangereuse en soi. L'arrêt d'un thread avec Fil.arrêter de causes pour débloquer tous les moniteurs qu'il a verrouillé (comme une conséquence naturelle de la décoché exception de ThreadDeath la propagation de la pile). Si l'un des objets préalablement protégé par ces moniteurs ont été dans un état incohérent, les objets endommagés deviennent visibles pour les autres threads, entraînant potentiellement arbitraire comportement.

C'est pourquoi vous devez avoir une garde..

16voto

Nathan Hughes Points 30377

La mauvaise partie sur l'utilisation d'un indicateur pour empêcher votre thread, c'est que si le thread est en attente ou de sommeil, alors vous devez attendre la fin de l'attente et de couchage. Si vous appelez la méthode d'interruption sur le thread qui sera la cause de l'attente du sommeil ou de l'appel à sortir avec une InterruptedException. Vous pouvez écrire la méthode run du thread afin que le InterruptedException est pris à l'extérieur quelle que soit la boucle logique que le thread est en train de faire.

L'appel de l'interruption() définit également une interruption de la propriété que vous pouvez utiliser comme un indicateur pour vérifier si pour arrêter de fumer (dans le cas où le fil n'est pas en attente ou en sommeil).

Voici une réponse à une question similaire, y compris des exemples de code.

10voto

Xorty Points 4967

Vous ne devriez pas tuer le fil d'un autre. C'est considéré comme une assez mauvaise habitude. Cependant, il y a beaucoup de façons. Vous pouvez utiliser les instructions return méthode run du thread. Ou vous pouvez vérifier si le fil a déjà été interrompu et ensuite il va annuler son travail. Fe:

 while (!isInterrupted()) { 
  // doStuff
}
 

5voto

Bart van Heukelom Points 11977

Faites un booléen volatil stop quelque part. Ensuite, dans le code qui tourne dans le fil, faites régulièrement

  if (stop) // end gracefully by breaking out of loop or whatever
 

Pour arrêter le fil, définissez stop sur true .

Je pense que vous devez le faire manuellement de cette façon. Après tout, seul le code exécuté dans le fil a une idée de ce qui est ou non gracieux.

3voto

Andreas_D Points 64111

Vous devez envoyer un message d'arrêt au thread et le thread lui-même doit agir si le message a été reçu. C'est assez facile, si l'action longue est dans la 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
     }
   }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X