Digamos que eu tenho um aplicativo que utiliza a Executor
estrutura como tal
Executors.newSingleThreadExecutor().submit(new Runnable(){
@Override
public void run(){
// do stuff
}
}
Quando eu executar esta aplicação no depurador, um thread é criado com o seguinte (default) Nome: Thread[pool-1-thread-1]
. Como você pode ver, isso não é muito útil e, até onde eu sei, o Executor
framework não fornece uma maneira fácil de nomear os threads ou pools de threads criados.
Então, como fornecer nomes para os threads / pools de threads? Por exemplo Thread[FooPool-FooThread]
,.
Você pode tentar fornecer sua própria fábrica de threads, que criará threads com nomes apropriados. Aqui está um exemplo:
fonte
Você também pode alterar o nome do seu segmento posteriormente, enquanto o segmento é executado:
Isso pode ser interessante se, por exemplo, você estiver usando o mesmo ThreadFactory para diferentes tipos de tarefas.
fonte
(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.)
. Se o ExecutorService substituir o segmento, ele será nomeado pelo ThreadFactory. Por outro lado, ver o nome desaparecer durante a depuração pode ser um indicador útil.O
BasicThreadFactory
from apache commons-lang também é útil para fornecer o comportamento de nomeação. Em vez de escrever uma classe interna anônima, você pode usar o Construtor para nomear os threads como desejar. Aqui está o exemplo dos javadocs:fonte
Se você estiver usando o Spring,
CustomizableThreadFactory
poderá definir um prefixo de nome de thread.Exemplo:
Como alternativa, você pode criar seu
ExecutorService
como um bean Spring usandoThreadPoolExecutorFactoryBean
- todos os threads serão nomeados com obeanName-
prefixo.No exemplo acima, os segmentos serão nomeados com
myExecutor-
prefixo. Você pode definir o prefixo explicitamente para um valor diferente (por exemplo"myPool-"
) configurandoexecutorFactoryBean.setThreadNamePrefix("myPool-")
no bean de fábrica.fonte
Há uma RFE aberta para isso com a Oracle. Pelos comentários do funcionário da Oracle, parece que eles não entendem o problema e não corrigem. É uma dessas coisas que é simples de suportar no JDK (sem quebrar a compatibilidade com versões anteriores), por isso é uma pena que a RFE seja mal compreendida.
Conforme indicado, você precisa implementar seu próprio ThreadFactory . Se você não deseja obter o Goiaba ou o Apache Commons apenas para esse fim, forneço aqui uma
ThreadFactory
implementação que você pode usar. É exatamente semelhante ao que você obtém do JDK, exceto pela capacidade de definir o prefixo do nome do encadeamento para algo diferente de "pool".Quando você deseja usá-lo, simplesmente tira proveito do fato de que todos os
Executors
métodos permitem que você forneça o seuThreadFactory
.este
dará um ExecutorService onde os threads são nomeados,
pool-N-thread-M
mas usandovocê receberá um ExecutorService em que os threads são nomeados
primecalc-N-thread-M
. Voila!fonte
ThreadGroup
favorThreadPoolExecutor
.Passe o ThreadFactory para um executorservice e você estará pronto
fonte
Uma maneira rápida e suja é usar
Thread.currentThread().setName(myName);
norun()
método.fonte
Estender ThreadFactory
public interface ThreadFactory
Thread newThread(Runnable r)
Código de amostra:
resultado:
.... etc
fonte
Como outras respostas já disseram, você pode criar e usar sua própria implementação da
java.util.concurrent.ThreadFactory
interface (não é necessária nenhuma biblioteca externa). Estou colando meu código abaixo porque é diferente das respostas anteriores, pois usa oString.format
método e usa um nome de base para os segmentos como um argumento construtor:E este é um exemplo de uso:
EDIT : tornando minha
ThreadFactory
implementação segura para threads , obrigado a @mchernyakov por apontá-la.Embora em nenhuma parte da
ThreadFactory
documentação se diga que suas implementações devam ser seguras contra threads, o fato deDefaultThreadFactory
ser seguro é uma grande dica:fonte
A principal solução Java doméstica que eu uso para decorar fábricas existentes:
Em ação:
fonte
fonte
Você pode escrever sua própria implementação do ThreadFactory, usando, por exemplo, alguma implementação existente (como defaultThreadFactory) e alterar o nome no final.
Exemplo de implementação do ThreadFactory:
E uso:
fonte
Eu uso para fazer o mesmo como abaixo (requer
guava
biblioteca):fonte
ThreadFactoryBuilder
é da biblioteca do Google Guava.Acho mais fácil usar um lambda como uma fábrica de threads, se você quiser apenas alterar o nome de um executor de thread único.
fonte
main@1, Finalizer@667, Reference Handler@668, Your name@665, Signal Dispatcher@666
Esta é minha fábrica personalizada, fornecendo nomes personalizados para analisadores de despejo de segmentos. Normalmente, dou apenas
tf=null
para reutilizar a fábrica de threads padrão da JVM. Este site possui uma fábrica de threads mais avançada.Para sua conveniência, este é um loop de despejo de threads para fins de depuração.
fonte