J'utilise un Le problème est que le nom est défini dans le fil lorsque le pool de threads est créé et n'est pas lié à la tâche que la piscine de thread est en cours d'exécution. Je comprends cela ... mes runnables et mes callables - bien qu'ils aient des noms - sont en réalité un niveau d'abstraction en baisse de la Il y a eu d'autres questions sur Stackoverflow sur la création de noms pour Ce que je veux savoir est: Quelqu'un a-t-il une bonne solution pour garder le nom du fil de piscine de thread en synchronisation avec l'exécution de celle-ci? P>
I.e. Si j'appelle Étant donné que cela concerne principalement le débogage et la journalisation, j'essaie d'éviter une solution qui implique de mettre un nouveau code dans chaque runnable qui pourrait être soumise au threadpoolexecutor - Je préfère simplement mettre du code dans la filefactoire ou enveloppez la threadpoolexecutor elle-même afin que le changement soit effectué au même endroit. Si une telle solution n'existe pas, je ne vais probablement pas déranger car ce n'est pas critique de mission. P>
commencez à modifier em> strong> pour clarifier, je sais que je peux mettre un Mon autre question, je suppose, est de savoir si les gens pensent que c'est une mauvaise idée de faire une telle chose. Devrais-je me méfier de mettre à jour le nom de la piscine de thread comme celui-ci? P>
Merci pour toute suggestion! p> threadpoolEcutor code> en Java pour gérer beaucoup de threads en cours d'exécution. J'ai créé mon propre simple
TrainFactory code> afin que je puisse donner aux threads meilleurs noms. P>
threadpoolEcutor code> S exécutant des threads. P>
threadpoolexecutor code> piscines de fil. (Voir Comment donner un nom à un fil appelable? et Comment nommer les discussions d'une piscine de fil dans Java .) P>
thread.getCurrentThread (). GetName () Code> Je l'aimerais pas em> pour renvoyer le nom de la piscine de thread de niveau supérieur, mais plutôt le nom de la Appelable / runnable que le thread est en cours d'exécution. P>
fil.CurrentTthread (). SetName ("Mon nom annulable"); Code> En tant que première ligne de chaque méthode de course d'exécution, mais j'essaie d'éviter de le faire. Je suis un perfectionniste ici, et je le réalise, donc je ne serai pas offensé si les gens veulent commenter cette question et me le dire. fin d'édition em> strong> p>
3 Réponses :
Ma suggestion serait d'essayer Vous pouvez également réinitialiser le nom lorsque vous avez terminé si vous le souhaitez. P> P>
Vous suggérez-vous que je fais cela chaque fois que je fais un appel à la piscine.execute ou que je remplace la méthode d'exécution de la piscine?
En supposant que vous souhaitez modifier le nom pour refléter le ce que ce thread est en train de faire, oui. Remarque: il changera lorsque le runnable démarre, non pas lorsque vous appelez invoke. ;)
Créer un threadpoolexecutor qui remplace la méthode BeforeExecute.
/** * Method invoked upon completion of execution of the given Runnable. * This method is invoked by the thread that executed the task. If * non-null, the Throwable is the uncaught <tt>RuntimeException</tt> * or <tt>Error</tt> that caused execution to terminate abruptly. * * <p><b>Note:</b> When actions are enclosed in tasks (such as * {@link FutureTask}) either explicitly or via methods such as * <tt>submit</tt>, these task objects catch and maintain * computational exceptions, and so they do not cause abrupt * termination, and the internal exceptions are <em>not</em> * passed to this method. * * <p>This implementation does nothing, but may be customized in * subclasses. Note: To properly nest multiple overridings, subclasses * should generally invoke <tt>super.afterExecute</tt> at the * beginning of this method. * * @param r the runnable that has completed. * @param t the exception that caused termination, or null if * execution completed normally. */ protected void afterExecute(Runnable r, Throwable t) { }
J'essaie réellement quelque chose comme ça maintenant, une bonne suggestion. Le seul problème est que la finalisation est complète, la piscine de thread a toujours ce nom. Malheureusement, la méthode postérieure ultérieure ne reçoit pas le fil dans lequel le courant est exécuté. J'aimerais pouvoir le nettoyer quand j'aurai fini aussi.
@JEFFEFFGLOLDBERG À AfterExecute, le thread.CurrentThread () est en réalité le fil que je définit le nom de Beforeexecute. Je mettrai à jour ma réponse pour démontrer cela.
Génial c'est génial. Merci!
J'ai fait un ajustement, et c'était pour ajouter un mappe
Aucun problème! Assurez-vous que vous utilisez un ConcurrentMap code> :) sinon vous pouvez rencontrer une boucle infinie! mailinator.blogspot.com/2009/06/Beautiful-race-condition. htm l
J'ai rencontré suffisamment de conditions de course dans ce système que je l'aurais déjà mis dans une carte synchronisée. Puisque je fais seulement des puts et supprime, il n'y a aucun avantage d'avoir les lectures rapides de ConcurrentMap. En outre, j'adore cet article que vous avez lié ... comme son auteur, moi aussi je suis toujours étrangement excité lorsque je découvre une condition de course.
Dans la réponse, il y a une question: "Je ne sais pas comment exactement DeriverunnaBename () fonctionnerait, peut-être tostring ()?". TOSTRING () ne semble pas fonctionner et que le fichier runnable dans BeforeExecute () n'est pas identique à celui que je suis passé à soumettre () Je ne sais pas comment accéder au nom d'origine des runnables.
@Zitrax Le DeriverunnaBename code> est vraiment spécifique à la mise en œuvre de l'exécution. Par exemple, si dans votre exécution, vous remplacez la méthode
tostring code> que vous obtiendriez le nom que vous attendiez
@Johnvint que j'ai fait remplacement de Tostring (), mais quand je débogé, je peux voir que le runnable que je soumets n'est pas ce que je vois dans beforeexecute () code>. Dans
beforeexecute () code> il imprime
java.util.concurrent.threadpoolexecutenter$worker@4516ee8c [stat e = -1, file d'attente vide] code> dans
Soumettre () code> Impression de mon
Tostring () code> Mise en œuvre. Je suppose donc que la mise en œuvre interne enveloppe mon exécutable dans un travailleur, à partir de laquelle mon original annulable n'est pas exposé.
@ZiTRAX, vous avez raison que le TPE enveloppera la runnable dans un futuretask. Je mettrai à jour ma réponse pour supporter Tostring code>
Donc, j'ai une solution qui gère les deux pour définir le nom et nettoyer après le nom. Merci à Peter Lawrey et John Vint pour leurs suggestions qui m'ont conduit ici. Étant donné que ni la suggestion ne manipulait pleinement mon problème, je pensais que je posterais ce code d'exemple comme une réponse distincte. Je m'excuse si c'est pauvre étiquette - si oui, laissez-moi savoir et je vais vous ajuster.
Dans le code ci-dessous, j'ai décidé de conserver le nom du thread de threadpoolEcutor d'origine et appendez le nom exécutable, puis dans le rejet enfin Le nom annulable pour nettoyer, mais cela peut être facilement modifié. p>
Comme John Vint suggère, je préférerais remplacer la méthode BeforeExecution code>, puis remplacer la méthode
après -execution code> pour nettoyer, mais le
Afterexecution code> n'a pas de poignée sur le fil. P>
public class RunnableNameThreadPoolExecutor extends ThreadPoolExecutor {
/* Constructors... */
@Override
public void execute(Runnable command) {
super.execute(new ManageNameRunnable(command));
}
private class ManageNameRunnable implements Runnable {
private final Runnable command;
ManageNameRunnable( Runnable command ) {
this.command = command;
}
public void run() {
String originalName = Thread.currentThread().getName();
try {
String runnableName = getRunnableName(command);
Thread.currentThread().setName(originalName+ ": " + runnableName);
command.run();
} finally {
Thread.currentThread().setName(originalName);
}
}
}
}
Avez-vous plus de code de travail? Telle que GetRunnaBename () Définition et exemple de code d'appel?
"Garder le nom du filetage de la piscine de thread en synchronisation avec l'exécutable qu'il est en cours d'exécution" -> Runnable / appelable ne définit pas un nom, je ne peux donc pas voir la poussée de votre question. Votre filefactory donne-t-il réellement un nom distinct un nom distinct?
Droite, chacun de mes runnables et des appelables implémenter une interface nommée, alors j'ai accès à des noms. Je me rends compte que je suis difficile dans lequel j'ai déjà implémenté une fonctionnalité spéciale pour tous mes runnables, mais je veux éviter d'ajouter du code supplémentaire qui définit manuellement le nom du thil.
Édité pour plus de clarté, modifiant une "piscine de thread" sur "thread" et un "fil" à "tâche".