J'ai besoin d'un "Runnable qui accepte un paramètre" bien que je sache qu'un tel runnable n'existe pas vraiment.
Cela peut indiquer une faille fondamentale dans la conception de mon application et / ou un blocage mental dans mon cerveau fatigué, j'espère donc trouver ici quelques conseils sur la façon d'accomplir quelque chose comme ce qui suit, sans violer les principes fondamentaux d'OO:
private Runnable mOneShotTask = new Runnable(String str) {
public void run(String str) {
someFunc(str);
}
};
Une idée comment accomplir quelque chose comme ci-dessus?
Consumer<T>
.Consumer<T>
Réponses:
Eh bien, cela fait presque 9 ans que j'ai publié ceci et pour être honnête, Java a apporté quelques améliorations depuis. Je vais laisser ma réponse originale ci-dessous, mais il n'est pas nécessaire que les gens fassent ce qu'il contient. Il y a 9 ans, lors de la révision du code, j'aurais demandé pourquoi ils l'avaient fait et peut-être l'avoir approuvé, peut-être pas. Avec les lambdas modernes disponibles, il est irresponsable d'avoir une réponse aussi votée recommandant une approche désuète (qui, en toute honnêteté, était douteuse au départ ...) Dans Java moderne, cette révision de code serait immédiatement rejetée, et ce serait suggéré:
Comme auparavant, des détails tels que la gestion de ce fil de manière significative sont laissés à l'exercice pour le lecteur. Mais pour le dire franchement, si vous avez peur d'utiliser des lambdas, vous devriez avoir encore plus peur des systèmes multithreads.
Réponse originale, juste parce que:
Vous pouvez déclarer une classe directement dans la méthode
la source
Vous pourriez le mettre dans une fonction.
(Quand j'ai utilisé ceci, mon paramètre était un identifiant entier, que j'ai utilisé pour créer un hashmap de ID -> myRunnables. De cette façon, je peux utiliser le hashmap pour publier / supprimer différents objets myRunnable dans un gestionnaire.)
la source
Runnable
objet retourné par la méthode existe n'importe où, leparamStr
ne sera probablement pas éligible pour le garbage collection. Il est possible que si l'objet existe mais ne peut plus jamais être exécuté, le JIT (ou même javac) décide de le supprimer de la portée, mais nous ne devons pas nous fier à de telles optimisations car elles peuvent changer dans le futur.Créez une fonction init qui renvoie l'objet lui-même et initialisez les paramètres avec lui.
la source
J'utilise la classe suivante qui implémente l' interface Runnable . Avec cette classe, vous pouvez facilement créer de nouveaux threads avec des arguments
la source
public RunnableArg(Object... args) { setArgs(args); }
puis décrire la classe locale:class ActionArg extends RunnableArg { public ActionArg(Object... arg) { super(arg); } @Override public void run() { /* getArgs() and process them */ } }
et l'utiliserThread t = new Thread(new ActionArg( %param_object(s)% )); t.start();
Vous avez deux options:
Définissez une classe nommée. Passez votre paramètre au constructeur de la classe nommée.
Faites fermer votre classe anonyme sur votre "paramètre". Assurez-vous de le marquer comme
final
.la source
Depuis Java 8, la meilleure réponse est d'utiliser
Consumer<T>
:https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html
C'est l'une des interfaces fonctionnelles, ce qui signifie que vous pouvez l'appeler comme une expression lambda:
la source
Je voudrais d'abord savoir ce que vous essayez d'accomplir ici pour avoir besoin d'un argument à passer à new Runnable () ou à run (). La méthode habituelle devrait être d'avoir un objet Runnable qui passe des données (str) à ses threads en définissant des variables membres avant de démarrer. La méthode run () utilise ensuite ces valeurs de variable membre pour exécuter someFunc ()
la source