What is ThreadFactory?
It is where we create each thread that will be used in our thread pool. The factory must implement the ThreadFactory interface and has a method that will be called by the pool if you need a new thread.
If you do not use a ThreadFactory we are explicitly used the default implementation that we can access through:
ThreadFactory factory = Executors.defaultThreadFactory();
When I should implement my own factory threads?
We should use it when we want to perform a single implementation for all threads that must be created through a thread pool we can implementing a specific thread factory. We will explain it better below across an exception handling example by a factory that make this treat .
How to handle exceptions in threads?
First we need to understand how the stacks of our threads .Each thread has its own stack. Follow the explanation below.
The JVM automatically creates the MAIN thread when we initialize our program, and it always starts at main method. The main is the first method in the stack methods. If we call a new method from the main, this is at the top of this stack :
This will also have its stack when initializing a new thread, regardless of the MAIN thread. The difference is that this cell starts with the run method of the Thread class, which in turn calls the run method of the task (Runnable):
This stack is also visible in the console output we got before, it shows the path that the exception outlined. It falls on top of the stack when an exception occurs in our code.
This exception will remove the stack method if no try-catch block:
The stack trace appears on the console if there is no other method in the stack:
Notice that the exception goes totally independent of the other stack. Even with the exception in the thread 1, the thread running MAIN will running. No works trying to catch the exception using a try-catch block.
The treatment of the exception will only happen if we put a try-catch within the run () for each thread. Thus we can handle the exception. Putting in the main we will not treat because the exception does not occur there but rather within each thread that is created through this.
@Override public void run() { try { System.out.println("here is the point "); new RuntimeException("New Exception in my thread"); } catch (RuntimeException e) { e.printStackTrace(); System.out.println("RuntimeException treated"); } }
How to centralize exception handling in threads?
You should imagine the scenario where multiple threads are created. Make a treatment using the try-catch block in each of them is no elegant. What do you think ?
In this way we can improve a little this by implementing a class for the interface: UncaughtExceptionHandler
Example:
private void myMethod() { Thread thread = new Thread(new Runnable() { public void run() { System.out.println("here is the point "); new RuntimeException("New Exception in my thread"); } }); // passando o objeto com a responsabilidade de tratamento de erro thread.setUncaughtExceptionHandler(new ThreatThreadException()); thread.start(); } public class ThreatThreadException implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("RuntimeException treated"); } }
We can treat it through the class that implement exception handling:
ThreatThreadException
Class which we define using the method:setUncaughtExceptionHandler
.
But that still implies in terms that make the call this way in each thread to create. That’s still not as practical. How to make this treatment to all threads at the same time?
We can put this treatment in our threadFactory. To implement the common behavior of all threads that will run in the pool of threads that are using it.
Observation : If you are in doubt about the thread pool worth just check out this previous post: https://dev4devs.com/2016/06/19/java-how-to-work-with-a-thread-pool/
Example:
this.threadPool = Executors.newFixedThreadPool(4, new
Factory
OfTheThreads());
public class Factory
OfTheThreads implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setUncaughtExceptionHandler(new ThreatThreadException());
return thread;
}
}
Ready ! Now all the threads that were created using this thread factory will have a handle exceptions by our exception handling class.