ThreadFactory

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??

  1. To set a more descriptive thread name. With the default ThreadFactory, it gives thread names in the form of pool-m-thread-n, such as pool-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 the ThreadPoolExecutor or ExecutorService is created.
  2. To set thread daemon status. The default ThreadFactory produces non-daemon threads.
  3. 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.

Download
You can download the full source code of this example here: ThreadFactoryExampleCode.zip

Want to know how to develop your skillset to become a Java Rockstar?

Join our newsletter to start rocking!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area

I have read and agree to the terms & conditions

 

Ashraf Sarhan

Ashraf Sarhan is a passionate software engineer, an open source enthusiast, has a Bsc. degree in Computer and Information Systems from Alexandria University. He is experienced in building large, scalable and distributed enterprise applications/service in multiple domains. He also has a keen interest in JavaEE, SOA, Agile and Big Data technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Phoenix0072
Phoenix0072
5 years ago

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).

nicolas
nicolas
4 years ago

for the missing L30-31 it should be I guess :
if (priority = %s”, priority, Thread.MIN_PRIORITY));
}

nicolas
nicolas
4 years ago

The mismatch is due to the < &lg; not encoded … : 2nd try:
if (priority &lg; Thread.MIN_PRIORITY) {
throw new IllegalArgumentException(String.format(“Thread priority (%s) must be >= %s”, priority, Thread.MIN_PRIORITY));
}

nicolas
nicolas
4 years ago

if (priority < Thread.MIN_PRIORITY) {
throw new IllegalArgumentException(String.format(“Thread priority (%s) must be >= %s”, priority, Thread.MIN_PRIORITY));
}
this should be good =)

Back to top button