java.util.concurrent.ThreadFactory Example
In this example we shall show you how to make use ThreadFactory
interface, ThreadFactory
is implemented by a user class to override its newThread()
method for on-demand creation of a new thread with a specific configuration like thread name, type(user
, daemon
) and priority, etc.
ThreadFactory vs default ThreadFactory:
In a typical Java ExecutorService
application where some threads will be assigned from the internal thread pool or created on-demand to perform tasks. Each ExecutorService
has an associated ThreadFactory
and a default ThreadFactory
if the application does not specify one. For non-trivial apps, it’s always a good idea to create a custom ThreadFactory
. Why??
- To set a more descriptive thread name. With the default
ThreadFactory
, it gives thread names in the form ofpool-m-thread-n
, such aspool-1-thread-1
,pool-2-thread-1
,pool-3-thread-1
, etc. When analyzing a thread dump, it’s hard to know their purpose and how they were started. So, using a descriptive thread name is the only clue to trace to the source where theThreadPoolExecutor
orExecutorService
is created. - To set thread daemon status. The default
ThreadFactory
produces non-daemon threads. - To set thread priority. The default
ThreadFactory
creates a normal priority threads.
Example:
CustomThreadFactoryBuilder
class is an elegant solution to be able to create customized thread factory instances for more than one thread pool using a thread factory builder mechanism. The ThreadFactory
interface has a single method called newThread(Runnable r)
which accepts a Runnable
type and returns a thread instance. Your factory logic goes into this method implementation where you create and configure the thread instance to set thread name, priority and daemon status, etc.
CustomThreadFactoryBuilder.java:
package com.jcg; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicLong; /** * @author ashraf * */ public class CustomThreadFactoryBuilder { private String namePrefix = null; private boolean daemon = false; private int priority = Thread.NORM_PRIORITY; public CustomThreadFactoryBuilder setNamePrefix(String namePrefix) { if (namePrefix == null) { throw new NullPointerException(); } this.namePrefix = namePrefix; return this; } public CustomThreadFactoryBuilder setDaemon(boolean daemon) { this.daemon = daemon; return this; } public CustomThreadFactoryBuilder setPriority(int priority) { if (priority = %s", priority, Thread.MIN_PRIORITY)); } if (priority > Thread.MAX_PRIORITY) { throw new IllegalArgumentException(String.format( "Thread priority (%s) must be <= %s", priority, Thread.MAX_PRIORITY)); } this.priority = priority; return this; } public ThreadFactory build() { return build(this); } private static ThreadFactory build(CustomThreadFactoryBuilder builder) { final String namePrefix = builder.namePrefix; final Boolean daemon = builder.daemon; final Integer priority = builder.priority; final AtomicLong count = new AtomicLong(0); return new ThreadFactory() { @Override public Thread newThread(Runnable runnable) { Thread thread = new Thread(runnable); if (namePrefix != null) { thread.setName(namePrefix + "-" + count.getAndIncrement()); } if (daemon != null) { thread.setDaemon(daemon); } if (priority != null) { thread.setPriority(priority); } return thread; } }; } }
SimpleTask
class implements Runnable
interface and prints the running thread properties (name
, priority
).
SimpleTask.java:
package com.jcg; /** * @author ashraf * */ public class SimpleTask implements Runnable { private long sleepTime; public SimpleTask(long sleepTime) { super(); this.sleepTime = sleepTime; } @Override public void run() { while (true) { try { System.out.println("Simple task is running on " + Thread.currentThread().getName() + " with priority " + Thread.currentThread().getPriority()); Thread.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } } } }
CustomThreadFactoryDemo
class creates a new customThreadfactory
using CustomThreadFactoryBuilder
class where we set the thread name prefix to DemoPool-Thread
, daemon status to false
and priority to MAX_PRIORITY
. So, all thread pool threads will be created with these properties. Then, it creates new ExecutorService
to execute three SimpleTask.
CustomThreadFactoryDemo.java:
package com.jcg; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; /** * @author ashraf * */ public class CustomThreadFactoryDemo { /** * @param args */ public static void main(String[] args) { ThreadFactory customThreadfactory = new CustomThreadFactoryBuilder() .setNamePrefix("DemoPool-Thread").setDaemon(false) .setPriority(Thread.MAX_PRIORITY).build(); ExecutorService executorService = Executors.newFixedThreadPool(3, customThreadfactory); // Create three simple tasks with 1000 ms sleep time SimpleTask simpleTask1 = new SimpleTask(1000); SimpleTask simpleTask2 = new SimpleTask(1000); SimpleTask simpleTask3 = new SimpleTask(1000); // Execute three simple tasks with 1000 ms sleep time executorService.execute(simpleTask1); executorService.execute(simpleTask2); executorService.execute(simpleTask3); } }
Output:
Simple task is running on DemoPool-Thread-0 with priority 10 Simple task is running on DemoPool-Thread-1 with priority 10 Simple task is running on DemoPool-Thread-2 with priority 10 Simple task is running on DemoPool-Thread-0 with priority 10 Simple task is running on DemoPool-Thread-1 with priority 10 Simple task is running on DemoPool-Thread-2 with priority 10 Simple task is running on DemoPool-Thread-0 with priority 10 Simple task is running on DemoPool-Thread-1 with priority 10 Simple task is running on DemoPool-Thread-2 with priority 10 Simple task is running on DemoPool-Thread-0 with priority 10 Simple task is running on DemoPool-Thread-1 with priority 10 Simple task is running on DemoPool-Thread-2 with priority 10
Download the Source Code of this example:
This was an example of how to use Java ThreadFactory
.
You can download the full source code of this example here: ThreadFactoryExampleCode.zip
Thanks for post. But I think your IF condition is a bit wrong coded or you’ve just missed something (CustomThreadFactoryBuilder class at 30-31 lines).
for the missing L30-31 it should be I guess :
if (priority = %s”, priority, Thread.MIN_PRIORITY));
}
The mismatch is due to the < ≶ not encoded … : 2nd try:
if (priority ≶ Thread.MIN_PRIORITY) {
throw new IllegalArgumentException(String.format(“Thread priority (%s) must be >= %s”, priority, Thread.MIN_PRIORITY));
}
if (priority < Thread.MIN_PRIORITY) {
throw new IllegalArgumentException(String.format(“Thread priority (%s) must be >= %s”, priority, Thread.MIN_PRIORITY));
}
this should be good =)