How to give name to a callable Thread?
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"));
user381878
Updated on June 24, 2020Comments
-
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 almost 14 yearsThreadFactory.newThread(runnable), but my task is Callable...!
-
Andreas almost 14 yearsYour
Callable
will be wrapped into ajava.util.concurrent.FutureTask
that implementsjava.util.concurrent.RunnableFuture
that implementsRunnable
. On the other hand it wouldn't make much sense thatThreadFactory
allows the thread creation only forRunnable
s whereasExecutorService
allows the submission ofCallable
s. -
user381878 almost 14 yearsthanks 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 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 over 11 yearsthis 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 whilerun()
is executing. for scheduled execution of short-term tasks, you'll see the default name in the debugger most of the time. -
ericsoco over 11 yearsmore on this here: javahowto.blogspot.com/2011/11/why-use-threadfactory.html
-
btiernay over 10 yearsGuava should (but doesn't seem to) have a utility method!
-
Gab about 9 yearsjust to be clear, do not forget the finally block....
-
PerwinCZ about 8 yearsThis worked perfectly! Thank you.
-
Luke Hutchison over 4 yearsYou need to shut down these
ExecutorService
instances when you have finished with them.