338 votes

Comment passer un paramètre à un Thread Java ?

Quelqu'un peut-il me suggérer comment passer un paramètre à un thread ?

De même, comment cela fonctionne-t-il pour les classes anonymes ?

6 votes

Pourriez-vous ajouter quelques explications supplémentaires sur ce que vous essayez de faire exactement ? Il y a beaucoup de techniques différentes, mais toutes dépendent de l'objectif final.

4 votes

Voulez-vous dire passer un paramètre à un thread déjà en cours ? Parce que toutes les réponses actuelles concernent le passage de paramètres à de nouveaux threads...

0 votes

Vous pouvez maintenant utiliser Consumer<T> .

421voto

Alnitak Points 143355

Vous devez passer le paramètre dans le constructeur à l'objet Runnable :

public class MyRunnable implements Runnable {

   public MyRunnable(Object parameter) {
       // store parameter for later user
   }

   public void run() {
   }
}

et l'invoquer ainsi :

Runnable r = new MyRunnable(param_value);
new Thread(r).start();

7 votes

@jasonm non, c'est un constructeur - les constructeurs n'ont pas de type de retour.

0 votes

Cela signifie que chaque Thread construit en utilisant r auront le même argument, donc si nous voulons passer des arguments différents à plusieurs Threads exécutant MyThread nous devrions créer un nouveau MyThread en utilisant l'argument souhaité pour chaque Thread. En d'autres termes, pour faire fonctionner un thread, nous devons créer deux objets : Thread et MyThread. Est-ce que cela est considéré comme mauvais, du point de vue des performances ?

2 votes

@IsaacKleinman Eh bien, vous devez le faire de toute façon, à moins que vous ne prolongiez Thread. Et cette solution fonctionne toujours dans ce cas - changez simplement "implements Runnable" en "extends Thread", "Runnable" en "Thread", et "new Thread(r)" en "r".

128voto

Nick Fortescue Points 18829

Pour les classes anonymes :

En réponse aux questions posées, voici comment cela fonctionne pour les classes anonymes.

   final X parameter = ...; // the final is important
   Thread t = new Thread(new Runnable() {
       p = parameter;
       public void run() { 
         ...
       };
   t.start();

Les classes nommées :

Vous avez une classe qui étend Thread (ou implémente Runnable) et un constructeur avec les paramètres que vous souhaitez passer. Ensuite, lorsque vous créez le nouveau thread, vous devez passer les arguments, puis démarrer le thread, quelque chose comme ceci :

Thread t = new MyThread(args...);
t.start();

Runnable est une bien meilleure solution que Thread BTW. Donc je préfère :

   public class MyRunnable implements Runnable {
      private X parameter;
      public MyRunnable(X parameter) {
         this.parameter = parameter;
      }

      public void run() {
      }
   }
   Thread t = new Thread(new MyRunnable(parameter));
   t.start();

Cette réponse est fondamentalement la même que celle de cette question similaire : Comment passer des paramètres à un objet Thread

2 votes

J'ai un code similaire à votre exemple de classe anonyme, sauf que j'ai accès à parameter directement à partir du run() sans utiliser un champ comme p du tout. Il semble fonctionner. Est-ce qu'il y a un truc subtil de multithreading que je rate en ne copiant pas parameter a p à l'avance ?

0 votes

Je pense qu'il vous manque un ) dans le premier exemple

0 votes

J'ai eu la même expérience que @RandallCook pour la classe Anonyme. Tant que j'avais le final X parameter avant le new Runnable() puis je pourrais accéder à parameter à l'intérieur de run() . Je n'avais pas besoin de faire le supplément p = parameter .

57voto

dfa Points 54490

Via le constructeur d'une classe Runnable ou Thread

class MyThread extends Thread {

    private String to;

    public MyThread(String to) {
        this.to = to;
    }

    @Override
    public void run() {
        System.out.println("hello " + to);
    }
}

public static void main(String[] args) {
    new MyThread("world!").start();
}

11 votes

+1 pour avoir montré comment le faire en étendant Thread au lieu d'implémenter Runnable.

1 votes

Pourquoi avons-nous besoin de la @Override pour ?

0 votes

@Snow the @Override indique explicitement qu'elle surcharge la méthode abstraite de la classe Thread.

18voto

jwoolard Points 1905

Lorsque vous créez un thread, vous avez besoin d'une instance de Runnable . La façon la plus simple de passer un paramètre est de le passer comme argument au constructeur :

public class MyRunnable implements Runnable {

    private volatile String myParam;

    public MyRunnable(String myParam){
        this.myParam = myParam;
        ...
    }

    public void run(){
        // do something with myParam here
        ...
    }

}

MyRunnable myRunnable = new myRunnable("Hello World");
new Thread(myRunnable).start();

Si vous souhaitez ensuite modifier le paramètre pendant l'exécution du thread, vous pouvez simplement ajouter une méthode setter à votre classe runnable :

public void setMyParam(String value){
    this.myParam = value;
}

Une fois que vous avez cela, vous pouvez changer la valeur du paramètre en appelant comme ceci :

myRunnable.setMyParam("Goodbye World");

Bien entendu, si vous souhaitez déclencher une action lorsque le paramètre est modifié, vous devrez utiliser des verrous, ce qui rend les choses considérablement plus complexes.

1 votes

L'ajout d'un passeur ne crée-t-il pas des conditions de course potentielles ? Si le thread démarre avec une valeur unique pour la variable mais que le setter la change en cours d'exécution, cela ne poserait-il pas problème ?

0 votes

Vrai, le setter et tous les accès au paramètre doivent être synchronisés.

7voto

PaulJWilliams Points 11641

Soit écrire une classe qui implémente Runnable, et passer ce dont vous avez besoin dans un constructeur convenablement défini, soit écrire une classe qui étend Thread avec un constructeur convenablement défini qui appelle super() avec les paramètres appropriés.

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