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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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:
01 02 03 04 05 06 07 08 09 10 11 12 | 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 =)