Avec ThreadPoolExecutor, comment obtenir le nom du thread en cours d'exécution dans le pool de threads?
Je suis en utilisant un ThreadPoolExecutor
en Java pour la gestion d'un lot de threads en cours d'exécution. J'ai créé mon propre simple ThreadFactory
afin que je puisse donner le filetage des meilleurs noms.
Le problème est que le nom est indiqué dans le Fil lorsque le pool de threads est d'abord créé et n'est pas liée à la tâche que le pool de threads est effectivement en cours d'exécution. Je comprends cela... mon Runnables et Callables--s'ils ont des noms, sont en fait un niveau d'abstraction vers le bas à partir de la ThreadPoolExecutor
'threads en cours d'exécution.
Il y a eu quelques autres questions sur StackOverflow sur la création de noms pour ThreadPoolExecutor
des pools de threads. (Voir Comment donner un nom à un objet appelable Fil? et Comment nommer le fils d'un pool de threads en Java.)
Ce que je veux savoir, c'est: quelqu'un aurait-il une bonne solution pour garder le nom du thread du pool en synchronisation avec l'Exécutable qu'il est effectivement en cours d'exécution?
c'est à dire Si je l'appelle Thread.getCurrentThread().getName()
j'aimerais qu'il pas pour renvoyer le nom de haut-niveau du pool de threads, mais plutôt le nom de la Callable/Praticable que le thread est actuellement en cours d'exécution.
Puisque c'est principalement pour le débogage et l'exploitation forestière, j'essaie d'éviter une solution qui consiste à moi de mettre un nouveau code dans tous les Exécutables qui peuvent être soumis à la ThreadPoolExecutor--je préfère juste mettre un peu de code dans le ThreadFactory ou enveloppez la ThreadPoolExecutor lui-même, de sorte que le changement est fait en un seul endroit. Si une telle solution n'existe pas, je n'aurai probablement pas la peine puisqu'il n'est pas essentiel à la mission.
commencer à modifier Pour clarifier, je sais que je peux mettre un Thread.currentThread().setName( "my runnable name" );
comme la première ligne de chaque Exécutable de l'exécution de la méthode, mais je vais essayer d'éviter de le faire. Je suis un perfectionniste ici, et je m'en rends compte, donc je ne serai pas offensé si les gens veulent faire des commentaires sur cette question et de me le dire. fin modifier
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 mise à jour du pool de threads nom comme ça?
Merci pour toutes les suggestions!
À droite, à chacune de mes Runnables et Callables de mettre en œuvre une interface, j'ai donc accès à des noms. Je me rends compte que je suis pointilleux et que j'ai déjà mis en place une fonction spéciale pour tous mes Runnables mais vous voulez éviter d'ajouter du code supplémentaire qui définit manuellement le nom du thread.
Édité pour plus de clarté, le changement de certains "pool de threads" de "thread" et certains "fils de" à "tâche".
OriginalL'auteur Jeff Goldberg | 2011-12-15
Vous devez vous connecter pour publier un commentaire.
Créer un ThreadPoolExecutor qui remplace la beforeExecute méthode.
Pas sûr de savoir comment exactement
derveRunnableName()
serait, peut-êtretoString()
?Edit: Le Fil.currentThread() est en fait le fil dans le beforeExecute qui appelle à la afterExecute. Vous pouvez faire référence à Fil.currentThread (), puis définissez le nom de la afterExecute. Ceci est indiqué dans la documentation javadoc
Modifier Les TPE se terminera le Praticable dans un FutureTask, afin de soutenir la
toString
méthode vous pourriez remplacernewTaskFor
et de créer votre propre enveloppé FutureTask.Dans afterExecute, le Fil.currentThread() est acutally le fil, je suis en train de le nom de beforeExecute. Je vais mettre à jour ma réponse à démontrer.
Génial c'est super. Merci!!!!
Pas De Problème! Assurez-vous que vous utilisez un
ConcurrentMap
🙂 Sinon, vous pouvez exécuter dans une boucle infinie! mailinator.blogspot.com/2009/06/beautiful-race-condition.htmlvous avez raison que les TPE se terminera le Praticable dans un FutureTask. Je vais mettre à jour ma réponse à l'appui de
toString
OriginalL'auteur John Vint
Donc, j'ai une solution qui gère à la fois pour définir le nom et le ménage après le nom. Merci à tous deux, Pierre Lawrey et John Vint pour leurs suggestions qui m'ont conduit ici. Étant donné que ni la suggestion entièrement résolue mon problème j'ai pensé poster cet exemple de code comme une réponse distincte. Je m'excuse si c'est de mauvaises manières--si oui, laissez-moi savoir et je vais régler.
Dans le code ci-dessous j'ai décidé de garder le nom de l'original ThreadPoolExecutor fil et ajouter le nom de l'Exécutable, puis dans le bloc finally supprimer le nom de l'Exécutable à nettoyer, mais qui peut être facilement modifié.
Comme John Vint l'indique, je préfère remplacer le
beforeExecution
méthode, puis remplacer leafterExecution
méthode pour nettoyer, mais leafterExecution
n'ont pas de poignée pour le thread.OriginalL'auteur Jeff Goldberg
Ma suggestion serait d'essayer
Vous pouvez également réinitialiser le nom lorsque vous avez terminé, si vous le souhaitez.
En supposant que vous souhaitez changer de nom afin de refléter le ce que ce thread est en train de faire, oui. Remarque: il va changer lorsque l'Exécutable démarre pas lorsque vous appelez invoquer. 😉
OriginalL'auteur Peter Lawrey