How to give name to a callable Thread?

73,215

Solution 1

You may use the overloaded method:

java.util.concurrent.Executors.newCachedThreadPool(ThreadFactory)

which allows you to pass a

java.util.concurrent.ThreadFactory

that should allow you to set the thread's names via java.util.concurrent.ThreadFactory.newThread(Runnable):

Constructs a new Thread. Implementations may also initialize priority, name, daemon status, ThreadGroup, etc.

Have a look at java.util.concurrent.Executors.DefaultThreadFactory for a default implementation.

Addendum

Since I see that this thread is still visited, Guava (if you have it available) provides a ThreadFactoryBuilder that leverages the need of having an inner anonymous class and even allows for customizing parametrized names for your threads.

Solution 2

I'm currently doing it somewhat like this:

    someExecutor.execute(new Runnable() {
        @Override public void run() {
            final String orgName = Thread.currentThread().getName();
            Thread.currentThread().setName(orgName + " - My custom name here");
            try {
                myAction();
            } finally {
                Thread.currentThread().setName(orgName);
            }
        }
    });

Solution 3

/**
 * The default thread factory
 */
static class DefaultThreadFactory implements ThreadFactory {
    static final AtomicInteger poolNumber = new AtomicInteger(1);
    final ThreadGroup group;
    final AtomicInteger threadNumber = new AtomicInteger(1);
    final String namePrefix;

    DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null)? s.getThreadGroup() :
                             Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" + 
                      poolNumber.getAndIncrement() + 
                     "-thread-";
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r, 
                              namePrefix + threadNumber.getAndIncrement(),
                              0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}

This is the original implementation in Java 1.5.0. So, you actually have the names as pool-x-thread where x stands for the order of the thread in the current thread group.

Solution 4

You should be careful when renaming threads when your threads are managed by a thread-pool because they are actually being reused over and over again for different tasks and once renamed, you might find that the thread names in your logs don't make any sense... In order to avoid that unwanted behavior you should make sure that once your Runnable/Callable finished the thread name is restored.

One way to implement this is by wrapping every Runnable/Callable that is executed by the thread-pool with a decorator which handles all of the needed clean-ups.

Solution 5

If you are using Spring, you may use org.springframework.scheduling.concurrent.CustomizableThreadFactory for that:

ExecutorService executorService = Executors.newCachedThreadPool(
                             new CustomizableThreadFactory("MyThreadNamePrefix"));
Share:
73,215
user381878
Author by

user381878

Updated on June 24, 2020

Comments

  • user381878
    user381878 almost 4 years

    I am executing a Callable Object using ExecutorService thread pool. I want to give a name to this thread.

    To be more specific, in older version I did this -

    Thread thread = new Thread(runnable Task);
    thread.setName("My Thread Name");
    

    I use thread name in log4j logging, this helps a lot while troubleshooting. Now I am migrating my code from Java 1.4 to Java 1.6. I have written this(Given below)- but I dont know how to give name to this thread.

    private final ExecutorService executorPool = Executors.newCachedThreadPool();
    Future<String> result = executorPool.submit(callable Task);
    

    Please give me some idea to give name to this thread?

  • user381878
    user381878 almost 14 years
    ThreadFactory.newThread(runnable), but my task is Callable...!
  • Andreas
    Andreas almost 14 years
    Your Callable will be wrapped into a java.util.concurrent.FutureTask that implements java.util.concurrent.RunnableFuture that implements Runnable. On the other hand it wouldn't make much sense that ThreadFactory allows the thread creation only for Runnables whereas ExecutorService allows the submission of Callables.
  • user381878
    user381878 almost 14 years
    thanks for your suggestion - I have found another alternative to do that- I am putting this as first line of my thread - Thread.currentThread().setName(this.client.getIdentityString‌​());
  • Tim Bender
    Tim Bender almost 14 years
    @user381878, You should heed the warning given by @Shai. Your Callable does not own the Thread it is running on in an ExecutorService. Unless every single Callable and Runnable you submit first changes the Thread's name, then you will eventually get inconsistent logs.
  • ericsoco
    ericsoco over 11 years
    this is simple and easy, but since it reverts to the default Thread name at the end of run(), you'll only see your custom name while run() is executing. for scheduled execution of short-term tasks, you'll see the default name in the debugger most of the time.
  • ericsoco
    ericsoco over 11 years
  • btiernay
    btiernay over 10 years
    Guava should (but doesn't seem to) have a utility method!
  • Gab
    Gab about 9 years
    just to be clear, do not forget the finally block....
  • PerwinCZ
    PerwinCZ about 8 years
    This worked perfectly! Thank you.
  • Luke Hutchison
    Luke Hutchison over 4 years
    You need to shut down these ExecutorService instances when you have finished with them.