web-dev-qa-db-fra.com

Comment arrêter un fil créé en implémentant une interface exécutable?

J'ai créé class en implémentant une interface exécutable, puis créé plusieurs threads (près de 10) dans une autre classe de mon projet.
Comment arrêter certains de ces fils?

53
svkvvenky

La méthode la plus simple consiste à interrupt() le, ce qui fera que Thread.currentThread().isInterrupted() renverra true , et peut également lancer un InterruptedException dans certaines circonstances où le fil est en attente en attente , par exemple Thread.sleep(), otherThread.join(), object.wait() etc.

Dans la méthode run(), vous devez intercepter cette exception et/ou vérifier régulièrement la valeur Thread.currentThread().isInterrupted() et faire quelque chose (par exemple, une sortie).

Remarque: Bien que Thread.interrupted() semble identique à isInterrupted(), il a un effet secondaire désagréable: appeler interrupted()efface le interrupted drapeau, alors que l'appel de isInterrupted() ne fonctionne pas.

D'autres méthodes sans interruption impliquent l'utilisation d'indicateurs "stop" (volatile) contrôlés par le thread en cours d'exécution.

72
Bohemian

Comment arrêter un fil créé en implémentant une interface exécutable?

Vous pouvez arrêter un thread de plusieurs manières, mais chacune d’elles prend un code spécifique pour le faire. Un moyen typique d'arrêter un thread est d'avoir un champ volatile boolean shutdown Que le thread vérifie de temps en temps:

  // set this to true to stop the thread
  volatile boolean shutdown = false;
  ...
  public void run() {
      while (!shutdown) {
          // continue processing
      }
  }

Vous pouvez également interrompre le fil qui cause sleep(), wait() et quelques autres méthodes pour lancer InterruptedException. Vous devriez également tester l'indicateur d'interruption de thread avec quelque chose comme:

  public void run() {
      while (!Thread.currentThread().isInterrupted()) {
          // continue processing
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              // good practice
              Thread.currentThread().interrupt();
              return;
          }
      }
  }

Notez que le fait d'interrompre un thread avec interrupt() va not lui faire forcer une exception immédiatement. Ce n'est que si vous utilisez une méthode qui est interruptible que le InterruptedException sera lancé.

Si vous voulez ajouter une méthode shutdown() à votre classe qui implémente Runnable, vous devez définir votre propre classe comme suit:

public class MyRunnable implements Runnable {
    private volatile boolean shutdown;
    public void run() {
        while (!shutdown) {
            ...
        }
    }
    public void shutdown() {
        shutdown = true;
    }
}
35
Gray

arrêt le fil à mi-chemin n'est pas une bonne pratique. Une méthode plus appropriée consiste à faire en sorte que le thread retourne par programmation. Laissez l'objet Runnable utiliser une variable partagée dans la méthode run(). Chaque fois que vous souhaitez que le thread s'arrête, utilisez cette variable comme indicateur.

EDIT: Exemple de code

class MyThread implements Runnable{

    private Boolean stop = false;

    public void run(){

        while(!stop){

            //some business logic
        }
    }
    public Boolean getStop() {
        return stop;
    }

    public void setStop(Boolean stop) {
        this.stop = stop;
    }       
}

public class TestStop {

    public static void main(String[] args){

        MyThread myThread = new MyThread();
        Thread th = new Thread(myThread);
        th.start();

        //Some logic goes there to decide whether to 
        //stop the thread or not. 

        //This will compell the thread to stop
        myThread.setStop(true);
    }
}
9
Santosh

Si vous utilisez ThreadPoolExecutor et que vous utilisez la méthode submit () , cela vous retournera un Future. Vous pouvez appeler cancel () sur le futur renvoyé pour arrêter votre tâche Runnable.

6
Kuldeep Jain

Arrêter (tuer) un fil à mi-chemin n'est pas recommandé. L'API est réellement obsolète.

Cependant, vous pouvez obtenir plus de détails, y compris des solutions de contournement, ici: Comment tuez-vous un fil de discussion en Java?

1
vaisakh

Thread.currentThread (). IsInterrupted () fonctionne superbement. Mais ce code ne fait que mettre en pause le minuteur.

Ce code est stop et réinitialise le compteur de threads.h1 est le nom du gestionnaire. Ce code est ajouté à l'intérieur de votre écouteur de clic sur le bouton. w_h = minutes w_m = millisecondes i = compteur

 i=0;
            w_h = 0;
            w_m = 0;


            textView.setText(String.format("%02d", w_h) + ":" + String.format("%02d", w_m));
                        hl.removeCallbacksAndMessages(null);
                        Thread.currentThread().isInterrupted();


                        }


                    });


                }`
0
Anish