Angenommen, ich habe eine Anwendung, die das Executor
Framework als solches verwendet
Executors.newSingleThreadExecutor().submit(new Runnable(){
@Override
public void run(){
// do stuff
}
}
Wenn ich diese Anwendung im Debugger ausführe, wird ein Thread mit dem folgenden (Standard-) Namen erstellt : Thread[pool-1-thread-1]
. Wie Sie sehen können, ist dies nicht besonders nützlich, und soweit ich das beurteilen kann, bietet das Executor
Framework keine einfache Möglichkeit, die erstellten Threads oder Thread-Pools zu benennen.
Wie geht man also vor, um Namen für die Threads / Thread-Pools bereitzustellen? Zum Beispiel Thread[FooPool-FooThread]
.
Sie können versuchen, eine eigene Thread-Factory bereitzustellen, die einen Thread mit den entsprechenden Namen erstellt. Hier ist ein Beispiel:
quelle
Sie können den Namen Ihres Threads auch später ändern, während der Thread ausgeführt wird:
Dies könnte von Interesse sein, wenn Sie beispielsweise dieselbe ThreadFactory für verschiedene Arten von Aufgaben verwenden.
quelle
(Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)
. Wenn der ExecutorService den Thread ersetzt, wird er von der ThreadFactory benannt. Andererseits könnte es ein nützlicher Indikator sein, den Namen beim Debuggen verschwinden zu sehen.Die
BasicThreadFactory
from apache commons-lang ist auch nützlich, um das Benennungsverhalten bereitzustellen. Anstatt eine anonyme innere Klasse zu schreiben, können Sie den Builder verwenden, um die Threads nach Ihren Wünschen zu benennen. Hier ist das Beispiel aus den Javadocs:quelle
Wenn Sie Spring verwenden,
CustomizableThreadFactory
können Sie dort ein Thread-Namenspräfix festlegen.Beispiel:
Alternativ können Sie Ihre
ExecutorService
als Spring Bean mit erstellenThreadPoolExecutorFactoryBean
- dann werden alle Threads mit dembeanName-
Präfix benannt.Im obigen Beispiel werden die Threads mit dem
myExecutor-
Präfix benannt. Sie können das Präfix explizit auf einen anderen Wert setzen (z. B."myPool-"
), indem Sie esexecutorFactoryBean.setThreadNamePrefix("myPool-")
auf der Factory Bean festlegen .quelle
Dafür gibt es bei Oracle eine offene RFE . Aus den Kommentaren des Oracle-Mitarbeiters geht hervor, dass er das Problem nicht versteht und es nicht beheben kann. Es ist eines dieser Dinge, das im JDK kinderleicht zu unterstützen ist (ohne die Abwärtskompatibilität zu beeinträchtigen). Es ist also eine Schande, dass die RFE missverstanden wird.
Wie bereits erwähnt, müssen Sie Ihre eigene ThreadFactory implementieren . Wenn Sie Guava oder Apache Commons nicht nur für diesen Zweck verwenden möchten, stelle ich hier eine
ThreadFactory
Implementierung zur Verfügung, die Sie verwenden können. Es ist genau dem ähnlich, was Sie vom JDK erhalten, mit der Ausnahme, dass das Thread-Namenspräfix auf etwas anderes als "Pool" gesetzt werden kann.Wenn Sie es verwenden möchten, nutzen Sie einfach die Tatsache, dass Sie mit allen
Executors
Methoden Ihre eigenen bereitstellen könnenThreadFactory
.Dies
gibt einen ExecutorService, in dem Threads benannt werden,
pool-N-thread-M
aber mitSie erhalten einen ExecutorService, in dem Threads benannt sind
primecalc-N-thread-M
. Voila!quelle
ThreadGroup
zugunsten von verwendetThreadPoolExecutor
.Übergeben Sie die ThreadFactory an einen Executorservice und Sie können loslegen
quelle
Ein schneller und schmutziger Weg ist die Verwendung
Thread.currentThread().setName(myName);
in derrun()
Methode.quelle
Erweitern Sie ThreadFactory
public interface ThreadFactory
Thread newThread(Runnable r)
Beispielcode:
Ausgabe:
....etc
quelle
Wie bereits in anderen Antworten erwähnt, können Sie eine eigene Implementierung der
java.util.concurrent.ThreadFactory
Schnittstelle erstellen und verwenden (keine externen Bibliotheken erforderlich). Ich füge meinen Code unten ein, weil er sich von den vorherigen Antworten unterscheidet, da er eineString.format
Methode verwendet und einen Basisnamen für die Threads als Konstruktorargument verwendet:Und dies ist ein Anwendungsbeispiel:
BEARBEITEN : Ich mache meine
ThreadFactory
Implementierung threadsicher, danke an @mchernyakov für den Hinweis.Obwohl nirgends in der
ThreadFactory
Dokumentation gesagt wird, dass seine Implementierungen threadsicher sein müssen, ist die Tatsache, dass dieDefaultThreadFactory
threadsicher ist, ein großer Hinweis:quelle
Die selbst entwickelte Java-Kernlösung, mit der ich vorhandene Fabriken dekoriere:
In Aktion:
quelle
quelle
Sie können Ihre eigene Implementierung von ThreadFactory schreiben, indem Sie beispielsweise eine vorhandene Implementierung (wie defaultThreadFactory) verwenden und den Namen am Ende ändern.
Beispiel für die Implementierung von ThreadFactory:
Und Verwendung:
quelle
Ich mache das gleiche wie unten (erfordert
guava
Bibliothek):quelle
ThreadFactoryBuilder
aus der Google Guava-Bibliothek stammt.Ich finde es am einfachsten, ein Lambda als Thread-Factory zu verwenden, wenn Sie nur den Namen für einen einzelnen Thread-Executor ändern möchten.
quelle
main@1, Finalizer@667, Reference Handler@668, Your name@665, Signal Dispatcher@666
Dies ist meine angepasste Fabrik, die angepasste Namen für Thread-Dump-Analysatoren bereitstellt. Normalerweise gebe ich nur,
tf=null
um die JVM-Standard-Thread-Factory wiederzuverwenden. Diese Website verfügt über eine erweiterte Thread-Factory.Für Ihre Bequemlichkeit ist dies eine Thread-Dump-Schleife für Debug-Zwecke.
quelle