ThreadFactory Interface in Java with Examples
Last Updated :
24 Jun, 2021
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
import java.io.*;
class GFG {
public static void main(String[] args)
{
// Creating a thread
Thread thread = new CustomThread();
thread.start(); // Starting execution of the created
// thread
}
}
// Creating a class that extends the Thread class
class CustomThread extends Thread {
@Override public void run()
{
System.out.println("This is a thread");
}
}
2. Creating a class that implements the Runnable interface and then using its object to create threads.
Java
/*package whatever //do not write package name here */
import java.io.*;
class GFG {
public static void main(String[] args)
{
// Creating a Runnable object
Runnable task = new Task();
// Creating a thread using the Runnable object
Thread thread = new Thread(task);
// Starting the execution of the created thread
thread.start();
}
}
class Task implements Runnable {
@Override public void run()
{
System.out.println("This is a thread");
}
}
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
import java.util.concurrent.ThreadFactory;
import java.io.*;
class CustomThreadFactory implements ThreadFactory {
// newThread is a factory method
// provided by ThreadFactory
public Thread newThread(Runnable command)
{
return new Thread(command);
}
}
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
// Java code to demonstrate ThreadFactory interface
import java.util.concurrent.ThreadFactory;
import java.io.*;
import java.util.ArrayList;
class ThreadFactoryExample {
public static void main(String[] args)
{
// Creating a CustomThreadFactory object
CustomThreadFactory threadFactory
= new CustomThreadFactory();
// Creating Runnable objects using the lambda
// expression
Runnable command1 = ()
-> System.out.println("Command 1 executed");
Runnable command2 = ()
-> System.out.println("Command 2 executed");
Runnable command3 = ()
-> System.out.println("Command 3 executed");
Runnable command4 = ()
-> System.out.println("Command 4 executed");
Runnable command5 = ()
-> System.out.println("Command 5 executed");
// Putting the commands in an ArrayList
ArrayList<Runnable> array = new ArrayList<>(5);
array.add(command1);
array.add(command2);
array.add(command3);
array.add(command4);
array.add(command5);
// creating threads and running them
for (Runnable command : array) {
threadFactory.newThread(command).start();
}
// print the thread count
System.out.println(
"Total number of threads created using CustomThreadFactory = "
+ threadFactory.getCount());
}
}
// ThreadFactory class
class CustomThreadFactory implements ThreadFactory {
// stores the thread count
private int count = 0;
// returns the thread count
public int getCount() { return count; }
// Factory method
@Override
public Thread newThread(Runnable command)
{
count++;
return new Thread(command);
}
}
OutputCommand 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.
Java
// Java program to demonstrate default
// ThreadFactory
import java.io.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
class DefaultThreadFactoryExample {
public static void main(String[] args)
{
// Default ThreadFactory
ThreadFactory threadFactory
= Executors.defaultThreadFactory();
for (int i = 1; i < 10; i++) {
// Creating new threads with the default
// ThreadFactory
Thread thread
= threadFactory.newThread(new Command());
// print the thread names
System.out.println(
"Name given by threadFactory = "
+ thread.getName());
// run the thread
thread.start();
}
}
}
class Command implements Runnable {
@Override public void run()
{
// Run some code
}
}
OutputName given by threadFactory = pool-1-thread-1
Name given by threadFactory = pool-1-thread-2
Name given by threadFactory = pool-1-thread-3
Name given by threadFactory = pool-1-thread-4
Name given by threadFactory = pool-1-thread-5
Name given by threadFactory = pool-1-thread-6
Name given by threadFactory = pool-1-thread-7
Name given by threadFactory = pool-1-thread-8
Name given by threadFactory = pool-1-thread-9
Note the names of threads given by default ThreadFactory. It has created 9 threads and all the threads are in the same ThreadGroup. All the threads are created using the same ThreadFactory(so the names of the threads are in form of pool -1 -thread-M).
Example:
Java
// Java program to demonstrate ThreadFactory
// using default implementation
import java.io.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
class DefaultThreadFactoryExample {
public static void main(String[] args)
{
for (int i = 1; i < 10; i++) {
// Default ThreadFactory
ThreadFactory threadFactory
= Executors.defaultThreadFactory();
// Creating new threads with the default
// ThreadFactory
Thread thread
= threadFactory.newThread(new Command());
// print the thread name
System.out.println(
"Name given by threadFactory = "
+ thread.getName());
// start the thread
thread.start();
}
}
}
class Command implements Runnable {
@Override public void run()
{
// Run some code
}
}
OutputName given by threadFactory = pool-1-thread-1
Name given by threadFactory = pool-2-thread-1
Name given by threadFactory = pool-3-thread-1
Name given by threadFactory = pool-4-thread-1
Name given by threadFactory = pool-5-thread-1
Name given by threadFactory = pool-6-thread-1
Name given by threadFactory = pool-7-thread-1
Name given by threadFactory = pool-8-thread-1
Name given by threadFactory = pool-9-thread-1
Here, We have used 9 different default ThreadFactories(in each loop we are creating a new one!). So each thread is in different ThreadGroup and thus the threads are given name in form of pool-N-thread-1.
The default ThreadFactory implementation creates non-daemon threads with normal priority and gives names in form of pool-N-thread-M which contains no information about how they work and what they do. This creates lots of problems in debugging and other important purposes. However, this problem can be solved using a custom ThreadFactory which can give more meaningful names to the threads and can set the daemon and priority statuses.
Methods of ThreadFactory
METHOD
| DESCRIPTION
|
---|
newThread(Runnable r) | Constructs a new Thread. |
Similar Reads
Java Tutorial Java is a high-level, object-oriented programming language used to build web apps, mobile applications, and enterprise software systems. It is known for its Write Once, Run Anywhere capability, which means code written in Java can run on any device that supports the Java Virtual Machine (JVM).Java s
10 min read
Java Interview Questions and Answers Java is one of the most popular programming languages in the world, known for its versatility, portability, and wide range of applications. Java is the most used language in top companies such as Uber, Airbnb, Google, Netflix, Instagram, Spotify, Amazon, and many more because of its features and per
15+ min read
Java OOP(Object Oriented Programming) Concepts Java Object-Oriented Programming (OOPs) is a fundamental concept in Java that every developer must understand. It allows developers to structure code using classes and objects, making it more modular, reusable, and scalable.The core idea of OOPs is to bind data and the functions that operate on it,
13 min read
Arrays in Java Arrays in Java are one of the most fundamental data structures that allow us to store multiple values of the same type in a single variable. They are useful for storing and managing collections of data. Arrays in Java are objects, which makes them work differently from arrays in C/C++ in terms of me
15+ min read
Inheritance in Java Java Inheritance is a fundamental concept in OOP(Object-Oriented Programming). It is the mechanism in Java by which one class is allowed to inherit the features(fields and methods) of another class. In Java, Inheritance means creating new classes based on existing ones. A class that inherits from an
13 min read
Collections in Java Any group of individual objects that are represented as a single unit is known as a Java Collection of Objects. In Java, a separate framework named the "Collection Framework" has been defined in JDK 1.2 which holds all the Java Collection Classes and Interface in it. In Java, the Collection interfac
15+ min read
Java Exception Handling Exception handling in Java allows developers to manage runtime errors effectively by using mechanisms like try-catch block, finally block, throwing Exceptions, Custom Exception handling, etc. An Exception is an unwanted or unexpected event that occurs during the execution of a program, i.e., at runt
10 min read
Java Programs - Java Programming Examples In this article, we will learn and prepare for Interviews using Java Programming Examples. From basic Java programs like the Fibonacci series, Prime numbers, Factorial numbers, and Palindrome numbers to advanced Java programs.Java is one of the most popular programming languages today because of its
8 min read
Java Interface An Interface in Java programming language is defined as an abstract type used to specify the behaviour of a class. An interface in Java is a blueprint of a behaviour. A Java interface contains static constants and abstract methods. Key Properties of Interface:The interface in Java is a mechanism to
12 min read
Polymorphism in Java Polymorphism in Java is one of the core concepts in object-oriented programming (OOP) that allows objects to behave differently based on their specific class type. The word polymorphism means having many forms, and it comes from the Greek words poly (many) and morph (forms), this means one entity ca
7 min read