ThreadFactory Interface in Java with Examples
The ThreadFactory interface defined in the java.util.concurrent package is based on the factory design pattern. As its name suggests, it is used to create new threads on demand. Threads can be created in two ways:
1. Creating a class that extends the Thread class and then creating its objects.
Java
2. Creating a class that implements the Runnable interface and then using its object to create threads.
Java
However, ThreadFactory is another choice to create new threads. This interface provides a factory method that creates and returns new threads when called. This factory method takes a Runnable object as an argument and creates a new thread using it.
The Hierarchy of ThreadFactory
java.util.concurrent ↳ Interface ThreadFactory
Implementation of ThreadFactory interface
Since ThreadFactory is an interface, the factory method defined inside it has to be implemented first in order to be used. Here is the simplest implementation of the ThreadFactory interface :
Java
Now, we can create objects of the CustomThreadFactory class and use its newThread(Runnable command) method to create new threads on demand. In the above implementation, the newThread method just creates a new thread by calling the Thread constructor which takes a Runnable command as the parameter.
There are many classes(such as ScheduledThreadPoolExecutor , ThreadPoolExecutor etc.) that use thread factories to create new threads when needed. Those classes have constructors that accept a ThreadFactory as argument. If any custom ThreadFactory is not given then they use the default implementation of ThreadFactory interface.
The Executors class in java.util.concurrent package provides Executors.defaultThreadFactory() static method that returns a default implementation of ThreadFactory interface.
Example: Below example code demonstrates ThreadFactory interface.
Java
«Total number of threads created using CustomThreadFactory line number43 index42 alt2″> + threadFactory.getCount());
Command 1 executed Command 2 executed Command 4 executed Command 3 executed Command 5 executed Total number of threads created using CustomThreadFactory = 5
Why use ThreadFactory?
In the above example, the newThread(Runnable) factory method ultimately creates a new thread using the given Runnable command. Then why use ThreadFactory? We could directly create threads from the Runnable commands by calling the Thread constructor that we did in the newThread(Runnable) method. Here are some reasons,
- We can give the threads more meaningful custom names. It helps in analyzing their purposes and how they work.
- We can have the statistics about the created threads like the count of threads and other details. We can restrict the creation of new threads based on the statistics.
- We can set the daemon status of threads.
- We can set the thread priority.
- We can have all the features confined in one class.
Default Thread Factory
It is the default thread factory that is implemented by the Executors.defaultThreadFactory() static method. This default ThreadFactory is used by many classes (such as ScheduledThreadPoolExecutor, ThreadPoolExecutor etc.) when they are not given any custom ThreadFactory. Those classes create new threads using the default ThreadFactory. This default ThreadFactory creates all the new threads in the same ThreadGroup(A ThreadGroup represents a group of threads). All the created new threads are non-daemon with priority set to the smallest of Thread.NORM_PRIORITY and the maximum priority permitted in the ThreadGroup. The threads created by this default ThreadFactory are given names in the form of pool-N-thread-M (As examples, pool-1-thread-1, pool-1-thread-2, pool-2-thread-1 etc.) where N is the sequence number of this factory, and M is the sequence number of the threads created by this factory.
Example: The below example demonstrates how the default ThreadFactory can be used.
Naming virtual threads
This post looks into naming virtual threads in three different ways. We will first use the virtual thread builder method. After that, we look into creating a thread factory and how to use it together with an ExecutorService.
Naming a virtual thread
In the following example, I set the name of the virtual thread using the builder method. When you create a thread using the static builder method ofVirtual() you can set the name using the .name() method.
When you run the previous thread the result in the console looks something like the following example. Notice that we can see me-name at the beginning. This is the name I gave the thread.
Naming Virtual threads using a factory
Naming a lot of virtual threads is easier with a factory. Using the same builder method ofVirtual() we can create a thread factory. You can do this by calling the .factory() method after setting the name.
In the following example, we create a factory and use it to create new virtual threads.
When you run the previous thread the result in the console looks something like the following example. Notice that we can see me-name at the beginning. This is the name I gave the thread.
Naming Virtual threads using an ExecutorService
To name virtual threads created by an ExecutorService you need to create your factory first. You can’t name virtual threads using the newVirtualThreadPerTaskExecutor . If you want to do so you need to use the newThreadPerTaskExecutor and a virtual thread factory. The end-result behaves the same, a virtual thread will be created for each task, but you will have full control over the factory.
In the following example, I create a virtual thread factory that names my virtual threads my-name followed by a number. Next, I pass this factory to the newThreadPerTaskExecutor. When I create virtual threads using the newThreadPerTaskExecutor they will get the name my-name followed by their number.
In the console, you can see their name appear followed by their number.
VirtualThread[email protected] VirtualThread[email protected]
Conclusion
You can name virtual threads using the static builder method .ofVirtual() . The same builder method can be used to create a factory to create new threads with or as input for an ExecutorService .
Further reading
More about virtual threads in Java:
Naming threads and thread-pools of ExecutorService
When I run this application in the debugger, a thread is created with the following (default) name: Thread[pool-1-thread-1] . As you can see, this isn’t terribly useful and as far as I can tell, the Executor framework does not provide an easy way to name the created threads or thread-pools. So, how does one go about providing names for the threads/thread-pools? For instance, Thread[FooPool-FooThread] .
20 Answers 20
Guava almost always has what you need.
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("my-sad-thread-%d").build()
and pass it off to your ExecutorService .
I’m not sure where to find «guava». There are a lot of parts to Google’s Guava and there are dozens of libraries with the same name. I assume you mean search.maven.org/artifact/com.google.guava/guava/29.0-jre/…. Is that right? The link you provide suggests it is from Google, but Google also has about half a dozen artifacts on Maven/Sonatype named «guava».
@Jason — If you are writing a non trivial Java project, you most likely should already have guava as a dependency. And here it is: github.com/google/guava
You could supply a ThreadFactory to newSingleThreadScheduledExecutor(ThreadFactory threadFactory) . The factory will be responsibe for creating threads, and will be able to name them.
Creating new threads
New threads are created using a ThreadFactory . If not otherwise specified, a Executors.defaultThreadFactory() is used, that creates threads to all be in the same ThreadGroup and with the same NORM_PRIORITY priority and non-daemon status. By supplying a different ThreadFactory , you can alter the thread’s name, thread group, priority, daemon status, etc. If a ThreadFactory fails to create a thread when asked by returning null from newThread , the executor will continue, but might not be able to execute any tasks
You can try to provide your own thread factory, which will create thread with appropriate names. Here’s one example:
class YourThreadFactory implements ThreadFactory < public Thread newThread(Runnable r) < return new Thread(r, "Your name"); >> Executors.newSingleThreadExecutor(new YourThreadFactory()).submit(someRunnable);
Executors.newSingleThreadExecutor < r ->Thread(r, "Your name") >
You can also change the name of your thread afterwards, while the thread is executed:
Thread.currentThread().setName("FooName");
That could be of interest if for instance you’re using the same ThreadFactory for different type of tasks.
This worked nicely because as FlorianT described, I have many different types of threads and didn’t want to have to create multiple ThreadFactory objects just for the name. I called Thread.currentThread().setName(«FooName»); as the first line in each run() method.
One minor issue with this is when the failure behavior described in the docs occurs: (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.) . If the ExecutorService replaces the thread, it will be named by the ThreadFactory. Then again, seeing the name disappear while debugging could be a useful indicator.
As the other answer says, this is a quick and dirty method to set the name, and if you do so with multiple threads, all will be have the same name!!
Might want to set the thread name back to original upon exit, because it may retain the name even if it is working on different unrelated tasks.
The BasicThreadFactory from apache commons-lang is also useful to provide the naming behavior. Instead of writing an anonymous inner class, you can use the Builder to name the threads as you want. Here’s the example from the javadocs:
// Create a factory that produces daemon threads with a naming pattern and // a priority BasicThreadFactory factory = new BasicThreadFactory.Builder() .namingPattern("workerthread-%d") .daemon(true) .priority(Thread.MAX_PRIORITY) .build(); // Create an executor service for single-threaded execution ExecutorService exec = Executors.newSingleThreadExecutor(factory);
If you are using Spring, there is CustomizableThreadFactory for which you can set a thread name prefix.
ExecutorService alphaExecutor = Executors.newFixedThreadPool(10, new CustomizableThreadFactory("alpha-"));
Alternatively, you can create your ExecutorService as a Spring bean using ThreadPoolExecutorFactoryBean — then the threads will all be named with the beanName- prefix.
@Bean public ThreadPoolExecutorFactoryBean myExecutor() < ThreadPoolExecutorFactoryBean executorFactoryBean = new ThreadPoolExecutorFactoryBean(); // configuration of your choice return executorFactoryBean; >
In the example above, the threads will be named with myExecutor- prefix. You can set the prefix explicitly to a different value (eg. «myPool-» ) by setting executorFactoryBean.setThreadNamePrefix(«myPool-«) on the factory bean.
There’s an open RFE for this with Oracle. From the comments from the Oracle employee it seems they don’t understand the issue and won’t fix. It’s one of these things that is dead simple to support in the JDK (without breaking backwards compatibility) so it is kind of a shame that the RFE gets misunderstood.
As pointed out you need to implement your own ThreadFactory. If you don’t want to pull in Guava or Apache Commons just for this purpose I provide here a ThreadFactory implementation that you can use. It is exactly similar to what you get from the JDK except for the ability to set the thread name prefix to something else than «pool».
package org.demo.concurrency; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; /** * ThreadFactory with the ability to set the thread name prefix. * This class is exactly similar to * * from JDK8, except for the thread naming feature. * * * The factory creates threads that have names on the form * prefix-N-thread-M, where prefix * is a string provided in the constructor, N is the sequence number of * this factory, and M is the sequence number of the thread created * by this factory. */ public class ThreadFactoryWithNamePrefix implements ThreadFactory < // Note: The source code for this class was based entirely on // Executors.DefaultThreadFactory class from the JDK8 source. // The only change made is the ability to configure the thread // name prefix. private static final AtomicInteger poolNumber = new AtomicInteger(1); private final ThreadGroup group; private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; /** * Creates a new ThreadFactory where threads are created with a name prefix * of prefix
. * * @param prefix Thread name prefix. Never use a value of "pool" as in that * case you might as well have used * . */ public ThreadFactoryWithNamePrefix(String prefix) < SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = prefix + "-" + poolNumber.getAndIncrement() + "-thread-"; >@Override 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; > >
When you want to use it you simply take advantage of the fact that all Executors methods allow you to provide your own ThreadFactory .
Executors.newSingleThreadExecutor();
will give an ExecutorService where threads are named pool-N-thread-M but by using
Executors.newSingleThreadExecutor(new ThreadFactoryWithNamePrefix("primecalc"));
you’ll get an ExecutorService where threads are named primecalc-N-thread-M . Voila!