Załóżmy, że mam aplikację, która korzysta z Executor
frameworka jako takiego
Executors.newSingleThreadExecutor().submit(new Runnable(){
@Override
public void run(){
// do stuff
}
}
Kiedy uruchomić tę aplikację w debugger, wątek jest tworzony z poniższej (domyślnie) imię: Thread[pool-1-thread-1]
. Jak widać, nie jest to szczególnie przydatne i, o ile mogę stwierdzić, Executor
framework nie zapewnia łatwego sposobu nazwania utworzonych wątków lub pul wątków.
Jak zatem można podać nazwy wątków / pul wątków? Na przykład Thread[FooPool-FooThread]
.
Możesz spróbować stworzyć własną fabrykę wątków, która utworzy wątek o odpowiednich nazwach. Oto jeden przykład:
źródło
Możesz także później zmienić nazwę swojego wątku, gdy wątek jest wykonywany:
Może to być interesujące, jeśli na przykład używasz tego samego ThreadFactory do różnego rodzaju zadań.
źródło
(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.)
. Jeśli ExecutorService zastępuje wątek, zostanie on nazwany przez ThreadFactory. Z drugiej strony zobaczenie, jak nazwa znika podczas debugowania, może być użytecznym wskaźnikiem.Z
BasicThreadFactory
apache commons-lang jest także przydatny do zapewnienia zachowania nazewnictwa. Zamiast pisać anonimową klasę wewnętrzną, możesz użyć Konstruktora, aby nazwać wątki według własnego uznania. Oto przykład z javadocs:źródło
Jeśli używasz Spring,
CustomizableThreadFactory
możesz ustawić prefiks nazwy wątku.Przykład:
Alternatywnie możesz utworzyć
ExecutorService
fasolę wiosenną za pomocąThreadPoolExecutorFactoryBean
- wtedy wszystkie wątki zostaną nazwane zbeanName-
prefiksem.W powyższym przykładzie wątki zostaną nazwane
myExecutor-
przedrostkiem. Możesz jawnie ustawić prefiks na inną wartość (np."myPool-"
), UstawiającexecutorFactoryBean.setThreadNamePrefix("myPool-")
na fasolę fabryczną.źródło
Jest do tego otwarty RFE z Oracle. Z komentarzy pracownika Oracle wynika, że nie rozumieją problemu i nie mogą go naprawić. Jest to jedna z tych rzeczy, które są bardzo proste w obsłudze w JDK (bez naruszania kompatybilności wstecznej), więc wstydem jest to, że RFE zostało źle zrozumiane.
Jak wskazano, musisz wdrożyć własny ThreadFactory . Jeśli nie chcesz pobierać Guava lub Apache Commons tylko w tym celu, podaję
ThreadFactory
implementację, z której możesz skorzystać. Jest dokładnie podobny do tego, co otrzymujesz z JDK, z wyjątkiem możliwości ustawienia prefiksu nazwy wątku na coś innego niż „pula”.Kiedy chcesz z niego skorzystać, po prostu skorzystaj z faktu, że wszystkie
Executors
metody pozwalają na zapewnienie własnychThreadFactory
.To
da ExecutorService, gdzie wątki są nazywane,
pool-N-thread-M
ale przy użyciudostaniesz ExecutorService, gdzie są nazywane wątki
primecalc-N-thread-M
. Voila!źródło
ThreadGroup
na rzeczThreadPoolExecutor
.Przekaż ThreadFactory do executorservice i możesz zacząć
źródło
Szybkim i brudnym sposobem jest użycie
Thread.currentThread().setName(myName);
tejrun()
metody.źródło
Rozszerz ThreadFactory
public interface ThreadFactory
Thread newThread(Runnable r)
Przykładowy kod:
wynik:
....itp
źródło
Jak już powiedziano w innych odpowiedziach, możesz utworzyć własną implementację
java.util.concurrent.ThreadFactory
interfejsu i korzystać z niej (nie są wymagane biblioteki zewnętrzne). Wklejam poniższy kod, ponieważ różni się on od poprzednich odpowiedzi, ponieważ używaString.format
metody i przyjmuje podstawową nazwę wątków jako argument konstruktora:A to jest przykład użycia:
EDYCJA : dzięki czemu moja
ThreadFactory
implementacja jest bezpieczna dla wątków, dzięki @mchernyakov za wskazanie tego.Chociaż nigdzie w
ThreadFactory
dokumentacji nie jest powiedziane, że jego implementacje muszą być bezpieczne dla wątków, fakt, żeDefaultThreadFactory
jest bezpieczny dla wątków, stanowi dużą wskazówkę:źródło
Domowe podstawowe rozwiązanie Java, którego używam do ozdabiania istniejących fabryk:
W akcji:
źródło
źródło
Możesz napisać własną implementację ThreadFactory, używając na przykład niektórych istniejących implementacji (takich jak defaultThreadFactory) i zmienić nazwę na końcu.
Przykład implementacji ThreadFactory:
I użycie:
źródło
Używam tego samego, co poniżej (wymaga
guava
biblioteki):źródło
ThreadFactoryBuilder
pochodzi z biblioteki Google Guava.Uważam, że najłatwiej jest użyć lambda jako fabryki wątków, jeśli chcesz tylko zmienić nazwę dla jednego modułu wykonującego wątek.
źródło
main@1, Finalizer@667, Reference Handler@668, Your name@665, Signal Dispatcher@666
To moja spersonalizowana fabryka zapewniająca niestandardowe nazwy analizatorów zrzutów wątków. Zwykle po prostu daję
tf=null
ponownie użyć domyślnej fabryki wątków JVM. Ta strona ma bardziej zaawansowaną fabrykę wątków.Dla Twojej wygody jest to pętla zrzutu wątku do celów debugowania.
źródło