ThreadFactory
is a Functional interface that provides a convenient a way to create new
threads on demand. ThreadFactory is used to decouple the process of thread
creation from the rest of your application's logic.
Definition of ThreadFactory interface
public interface ThreadFactory {
Thread newThread(Runnable r);
}
The newThread method takes a Runnable object as a parameter and returns a new Thread object.
For example, following CustomThreaFactory class generate thread with priority 7.
CustomThreadFactory.java
package com.sample.app.threads;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class CustomThreadFactory implements ThreadFactory{
private int threadCount = 1;
@Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setName("MyThread-" + threadCount++);
thread.setPriority(7);
return thread;
}
}
‘CustomThreadFactoryDemo’ use CustomThreadFactory to create new threads for you.
CustomThreadFactoryDemo.java
package com.sample.app;
import java.util.Random;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import com.sample.app.threads.CustomThreadFactory;
public class CustomThreadFactoryDemo {
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println(Thread.currentThread().getName() + " executing this code");
sleepRandomSeconds(5);
System.out.println(Thread.currentThread().getName() + " finished executing this code");
};
ThreadFactory threadFactory = new CustomThreadFactory();
for(int i = 0; i<10; i++) {
threadFactory.newThread(runnable).start();
}
}
private static void sleepRandomSeconds(int upperBound) {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(upperBound));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Sample Output
MyThread-1 executing this code MyThread-2 executing this code MyThread-3 executing this code MyThread-4 executing this code MyThread-5 executing this code MyThread-6 executing this code MyThread-7 executing this code MyThread-8 executing this code MyThread-9 executing this code MyThread-10 executing this code MyThread-10 finished executing this code MyThread-1 finished executing this code MyThread-4 finished executing this code MyThread-3 finished executing this code MyThread-7 finished executing this code MyThread-2 finished executing this code MyThread-5 finished executing this code MyThread-6 finished executing this code MyThread-8 finished executing this code MyThread-9 finished executing this code
In this example, CustomThreadFactory implements the ThreadFactory interface and overrides the newThread method. It uses the defaultThreadFactory() method from Executors to create the underlying Thread object and then customizes the thread's name by appending a count to it, and set the priority to 7.
Using Custom Thread factory, we can customize the thread creation in number of ways, for example, we can
a. Set the thread name prefix
b. Set the thread priority
c. Set the thread daemon status
d. Set the thread stack size
e. Set the thread security context
f. Create threads from a specific thread group
Let’s improvise CustomThreadFactory by passing the thread priority as argument.
CustomThreadFactory.java
package com.sample.app.threads;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public class CustomThreadFactory implements ThreadFactory{
private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
private int priority;
public CustomThreadFactory(int priority) {
this.priority = priority;
}
@Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setName("MyThread-" + THREAD_COUNT.incrementAndGet());
thread.setPriority(priority);
return thread;
}
}
Use ThredFactory in ThreadPool consruction
ThreadPoolExecutor executorService = new ThreadPoolExecutor(10, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new CustomThreadFactory(7));
The executor service will now use the CustomThreadFactory to create new threads as needed. All of the new threads will have the name prefix "MyThread-" and the thread priority 7.
Find the below working application.
ThreadPoolDemo.java
package com.sample.app;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.sample.app.threads.CustomThreadFactory;
public class ThreadPoolDemo {
private static void sleepRandomSeconds(int upperBound) {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(upperBound));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
ThreadPoolExecutor executorService = new ThreadPoolExecutor(10, 20, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(), new CustomThreadFactory(7));
Runnable runnable = () -> {
System.out.println(Thread.currentThread().getName() + " executing this code");
sleepRandomSeconds(5);
System.out.println(Thread.currentThread().getName() + " finished executing this code");
};
for(int i=0; i < 10; i++) {
executorService.submit(runnable);
}
executorService.shutdown();
}
}
Sample Output
MyThread-1 executing this code MyThread-3 executing this code MyThread-2 executing this code MyThread-4 executing this code MyThread-5 executing this code MyThread-3 finished executing this code MyThread-6 executing this code MyThread-7 executing this code MyThread-8 executing this code MyThread-9 executing this code MyThread-10 executing this code MyThread-10 finished executing this code MyThread-9 finished executing this code MyThread-4 finished executing this code MyThread-7 finished executing this code MyThread-6 finished executing this code MyThread-2 finished executing this code MyThread-1 finished executing this code MyThread-8 finished executing this code MyThread-5 finished executing this code
No comments:
Post a Comment