51 votes

Comment démarrer / arrêter / redémarrer un thread en Java?

J'éprouve une réelle difficulté à trouver un moyen de démarrer, arrêter et redémarrer un thread en Java.

Plus précisément, j'ai une classe de Tâches (actuellement implements Runnable) dans un fichier Task.java. Ma principale de l'application doit être en mesure de COMMENCER cette tâche sur un fil, ARRÊT (tuer) le fil lorsqu'il en a besoin, et parfois à TUER et REDÉMARRER le fil ...

Ma première tentative a été avec ExecutorService mais je n'arrive pas à trouver un moyen pour qu'il redémarrer une tâche. Lorsque j'utilise .shutdownnow() tout appel d' .execute(..) échoue parce que le ExecutorService est "shutdown"...

Alors, comment pourrais-je accomplir? Toute aide serait grandement appréciée.... Merci,

48voto

Taylor Leese Points 18895

Une fois qu'un thread s'arrête vous ne pouvez pas redémarrer. Cependant, il n'y a rien qui vous empêche de créer et de commencer un nouveau thread.

Option 1: Créer un nouveau fil de discussion plutôt que d'essayer de redémarrer.

Option 2: au Lieu de laisser le fil d'arrêt, ont-il attendre et puis quand il reçoit une notification vous pouvez lui permettre de le faire fonctionner à nouveau. De cette façon, le fil ne s'arrête jamais et n'aura jamais besoin d'être redémarré.

Edit basé sur les commentaires:

Pour "tuer" le fil que vous pouvez faire quelque chose comme ce qui suit.

yourThread.setIsTerminating(true); // tell the thread to stop
yourThread.join(); // wait for the thread to stop

10voto

Matt Crinklaw-Vogt Points 5824

Il est impossible de mettre fin à un fil, à moins que le code qui s'exécute dans le thread vérifie et autorise la résiliation.

Vous avez dit: "Malheureusement, je dois tuer/redémarrer ... je n'ai pas le contrôle complet sur le contenu de la discussion et pour ma situation, il nécessite un redémarrage"

Si le contenu du fil ne permettent pas la résiliation de son exectuion alors vous ne pouvez pas mettre fin à ce thread.

Dans votre post, vous avez dit: "Ma première tentative a été avec ExecutorService mais je n'arrive pas à trouver un moyen pour qu'il redémarrer une tâche. Lorsque j'utilise .shutdownnow()..."

Si vous regardez le code source de "shutdownnow" il traverse et interrompt les threads en cours d'exécution. Ce ne sera pas cesser de leur exécution, sauf si le code dans les discussions des vérifications pour voir si elle a été ineterrupted et, dans l'affirmative, s'arrête l'exécution elle-même. Donc shutdownnow est probablement pas faire ce que vous pensez.

Permettez-moi d'illustrer ce que je veux dire quand je dis que le contenu de la thread doit permettre que le fil à la fin:

myExecutor.execute(new Runnable() {
 public void run() {
  while (true) {
    System.out.println("running");
  }
 }
 });
myExecutor.shutdownnow();

Ce thread va continuer à courir pour toujours, même si shutdownnow a été appelé, car il ne vérifie s'il a été résilié ou non. Ce fil de discussion, cependant, va s'arrêter:

myExecutor.execute(new Runnable() {
 public void run() {
  while (!Thread.interrupted()) {
    System.out.println("running");
  }
 }
 });
myExecutor.shutdownnow();

Depuis ce thread vérifie pour voir si oui ou non il a été interrompu / arrêt / fin.

Donc, si vous voulez un fil que vous pouvez arrêter, vous devez vous assurer qu'elle vérifie si elle a été interrompue. Si vous voulez un sujet que vous pouvez "arrêter" et "redémarrer", vous pouvez faire un exécutable qui peut prendre de nouvelles tâches comme il a été mentionné avant.

Pourquoi ne pouvez-vous pas arrêter un thread en cours d'exécution? Eh bien, j'en fait menti, vous pouvez l'appeler "yourThread.stop()" mais pourquoi est-ce une mauvaise idée? Le fil pourrait être synchronisés (ou d'autres de la section critique, mais nous nous limiterons à setions gardé par le syncrhonized mot clé ici) section de code lorsque vous l'arrêtez. synchroniser les blocs sont censés être exécutée dans leur entirity et par un seul thread avant d'être consulté par un autre thread. Si vous arrêter un thread dans le milieu d'une synchronisation de bloc, la protection mis en place par la synchronisation de bloc est invalidé et que votre programme va entrer dans un état inconnu. Les développeurs à mettre des choses dans la synchronisation des blocs de garder les choses en synchro, si vous utilisez threadInstance.stop() vous détruire le sens de la synchronisation, ce que le développeur de ce code tente d'accomplir et comment le développeur de ce code devrait son synchronisé blocs à se comporter.

10voto

T.J. Crowder Points 285826

Examen java.lang.Thread.

Pour démarrer ou redémarrer (une fois qu'un thread est arrêté, vous ne pouvez pas redémarrer le même fil, mais il n'a pas d'importance; il suffit de créer un nouveau Thread exemple):

// Create your Runnable instance
Task task = new Task(...);

// Start a thread and run your Runnable
Thread t = new Thread(task);

Pour l'arrêter, avoir une méthode sur votre Task de l'instance qui définit un indicateur pour dire l' run méthode de la sortie, de retour d' run des sorties sur le fil. Si votre code d'appel a besoin de connaître le thread a vraiment arrêté avant qu'il retourne, vous pouvez utiliser join:

// Tell Task to stop
task.setStopFlag(true);

// Wait for it to do so
t.join();

Concernant le redémarrage: Même si un Thread ne peut pas être redémarré, vous pouvez réutiliser votre Runnable exemple avec un nouveau thread si elle a de l'etat et de ce fait, vous voulez garder, qui vient pour la même chose. Assurez-vous que votre Runnable est conçu pour permettre à plusieurs appels d' run.

5voto

ChadNC Points 1655

Vous ne pouvez pas redémarrer un thread, donc votre meilleure option est de sauvegarder l'état actuel de l'objet au moment où le fil a été arrêté et lorsque les opérations doivent continuer sur cet objet, vous pouvez recréer l'objet en utilisant les sauvés et puis commencer le nouveau thread.

Ces deux articles Swing Travailleur et de Simultanéité peut vous aider à déterminer la meilleure solution à votre problème.

0voto

Uri Points 50687

Il y a une différence entre faire une pause d'un fil et de la mettre en attente. Si l'arrêt pour vous dire tuer le fil, puis un redémarrage signifie simplement créer un nouveau thread et le lancement.

Il existe des méthodes pour tuer les fils à partir d'un autre thread (par exemple, votre reproducteur), mais ils sont dangereux en général. Il pourrait être plus sûr si votre fil vérifie en permanence certaines drapeau pour savoir s'il doit continuer (je suppose que il y a certains boucle dans votre thread), et ont l'externe "contrôleur" modifier l'état du pavillon.

Vous pouvez voir un peu plus: http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

Puis-je vous demander pourquoi vous voulez tuer le fil et de le redémarrer? Pourquoi ne pas avoir juste attendre jusqu'à ce que ses services sont de nouveau nécessaire? Java a la synchronisation des mécanismes exactement à cette fin. Le fil sera de dormir jusqu'à ce que le contrôleur de la notifie à poursuivre l'exécution.

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