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

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