47 votes

Pourquoi ne pas démarrer un thread dans le constructeur? Comment résilier?

Je suis en train d'apprendre comment utiliser les threads en Java. Et j'ai écrit une classe qui implémente Runnable pour s'exécuter simultanément à un autre thread. Le thread principal poignées en écoutant le port série sur lequel le deuxième thread va gérer l'envoi de données vers le même port.

public class MyNewThread implements Runnable {
    Thread t;

    MyNewThread() {
        t = new Thread (this, "Data Thread");
        t.start();
    }

    public void run()  {
        // New Thread code here 
    }

Il y a d'abord thread commence la deuxième comme ceci:

public class Main {
    public static void main(String[] args) throws Exception{
        new MyNewThread();
        // First thread code there
    }  
}

Cela fonctionne, mais mon compilateur drapeaux d'avertissement en disant: Il est dangereux de commencer un nouveau thread dans le constructeur. Pourquoi est-ce?

La deuxième partie de cette question est: comment faire si j'ai une boucle exécute dans un thread (le port série écouter fil) et je tape une commande quitter dans mon deuxième thread. Comment puis-je obtenir le premier thread pour mettre fin? Merci.

45voto

Justin Waugh Points 1901

Pour votre première question: à Partir d'un thread à un constructeur en passant en this s'échappe this. Cela signifie que vous êtes réellement donner une référence de votre objet avant qu'il est entièrement construit. Le fil avant de commencer votre constructeur de finitions. Cela peut entraîner toutes sortes de comportements bizarres.

Pour votre deuxième question: Il n'est pas acceptable moyen de forcer un autre thread pour arrêter en Java, donc vous devez utiliser une variable dont le fil serait de vérifier pour savoir si oui ou non elle doit s'arrêter. L'autre thread serait réglé pour indiquer que le premier thread s'arrête. La variable doit être volatile ou tous les accès synchronisé pour assurer la bonne publication. Voici un code qui serait quelque chose comme ce que vous voulez.

public class MyNewThread implements Runnable {

    private final Thread t;
    private volatile boolean shouldStop = false;

    MyNewThread() {
        t = new Thread (this, "Data Thread");
    }

    public void start() {
        t.start();
    }

    public void stop() {   
         shouldStop = true;
    }

    public void run()  {
         while(!shouldStop)
         {
             // do stuff
         }
    }
}

Ce que veut créer et démarrer le thread n':

MyNewThread thread = new MyNewThread();
thread.start();

Ce que veut arrêter le fil serait de faire:

thread.stop();

9voto

John Vint Points 19804

Permet de jeter un oeil à un exemple de base:

class MyClass implements Runnable{
   int a = 0;
   String b = null;

   public MyClass(){
       new Thread(this).start();
       b = "Foo";
   }

   public void run(){
      a = b.length(); //can throw NullPointerException
   }
}

Dans ce cas, le MyClass.ce qui est dit à échapper le constructeur. Cela signifie que l'objet est disponible pour référence mais l'ensemble de ses champs qui sont en cours de construction dans le constructeur ne peut pas être créé. Pour cela prendre à un autre niveau que si b a final Vous attendons à être disponibles, mais il n'est pas assurée. Ceci est connu comme partiellement construit les objets et est parfaitement légal en java.

0voto

user1841718 Points 26

à propos de la deuxième question, vous pouvez vérifier si le deuxième thread a été terminé ou non par la méthode isAlive et si oui, utilisez le mot clé break pour désactiver le bouclage du premier thread, puis il sera terminé si rien a a faire

entrez le code ici

 public class MyNewThread implements Runnable {
Thread t;

MyNewThread() {
    t = new Thread (this, "Data Thread");
    t.start();
}

public void run()  {

   reading code ................
    // New Thread code here 
}
 

entrez le code ici

  public class Main {
public static void main(String[] args) throws Exception{
   MyNewThread thread = new MyNewThread();

while(true)
{
    listening code ...................

    if(!thread.t.isAlive())
      break;
 }

}  
}
 

-4voto

Mike Thomsen Points 12074

La deuxième partie de cette question est: comment faire si j'ai une boucle en cours d'exécution dans un thread (le thread d'écoute du port série) et que je tape une commande de sortie dans mon deuxième thread. Comment terminer le premier thread?

Faites-le continuer à boucler jusqu'à ce qu'une condition soit atteinte. Par exemple:

 public void run() {
    while ( !inputConsole.getCommand().equals("exit") ) {
        //Do Something
        Thread.sleep(1000); //put thread to sleep for 1 second
    }
}
 

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