Can someone briefly explain on HOW and WHEN to use a ThreadFactory? An example with and without using ThreadFactory might be really helpful to understand the differences.
Thanks!
Can someone briefly explain on HOW and WHEN to use a ThreadFactory? An example with and without using ThreadFactory might be really helpful to understand the differences.
Thanks!
The factory pattern is a creational design pattern used in software development to encapsulate the processes involved in the creation of objects.
Let's assume, we have some worker threads for different tasks and want them with special names (like for debugging purposes). So we could implement a ThreadFactory:
public WorkerThreadFactory implements ThreadFactory {
private int counter = 0;
private String prefix = "";
public WorkerThreadFactory(String prefix) {
this.prefix = prefix;
}
public Thread newThread(Runnable r) {
return new Thread(r, prefix + "-" + count++);
}
}
If you had such a requirement, it would be pretty difficult to implement it without a factory or builder pattern.
ThreadFactory
is part of the Java API because it is used by other classes too. So the example above shows, why we should use 'a factory to create Threads' in some occasions but, of course, there is absolutely no need to implement java.util.concurrent.ThreadFactory
to accomplish this task.
Here's one possible usage. If you have an executor service which executes your runnable tasks in multithreaded fashion and once in a while your thread die from an uncaught exception. Let's assume that you wan't to log all these exceptions. ThreadFactory
solves this problem:
ExecutorService executor = Executors.newSingleThreadExecutor(new LoggingThreadFactory());
executor.submit(new Runnable() {
@Override
public void run() {
someObject.someMethodThatThrowsRuntimeException();
}
});
LoggingThreadFactory
can be implemented like this one:
public class LoggingThreadFactory implements ThreadFactory
{
@Override
public Thread newThread(Runnable r)
{
Thread t = new Thread(r);
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException(Thread t, Throwable e)
{
LoggerFactory.getLogger(t.getName()).error(e.getMessage(), e);
}
});
return t;
}
}
As mentioned by "InsertNickHere", you'll have to understand the Factory Pattern.
A good example for a use of a ThreadFactory is the ThreadPoolExecutor: The Executor will create Threads if necessary and take care of the pooling. If you want to step in at the creation process and give special names to the created Threads, or assign them to a ThreadGroup, you can create a ThreadFactory for that purpose and give it to the Executor.
It's a little bit IoC-style.
IMHO the single most important function of a ThreadFactory
is naming threads something useful. Having threads in a stacktrace named pool-1-thread-2
or worse Thread-12
is a complete pain when diagnosing problems.
Of course, having a ThreadGroup
, daemon status and priority are all useful too.