Always Name Your Thread Pools
Our software tends to use a lot of thread pools – mostly through java.util.concurrent.ExecutorService
implementations (Created via Executors.new...
. We create these for various async use-cases, and they can be seen all over the place. All of these executors have a thread factory. It’s hidden in the default factory method, but you can supply a thread factory. If not supplied, a default thread factory is used whenever a thread is needed.
When using spring, those can be created using <task:executor />
. In that case, each executor service’s thread factory is provided by spring and it uses the name of the executor bean (specified with id="executorName"
). But for those not created by spring, a default name is used which isn’t helpful and doesn’t let you differentiate threads by name.
And you need to differentiate threads by name – in case of performance issues you have various options to investigate: thread dumps and using the top command. In both cases it’s useful to know what function does a thread service, as the stacktrace in the dump might not always be revealing.
And my favorite tool for quick investigation is top
. More precisely, top -H -p <pid>
. This shows the usual top table, but the -H flag means that threads for the chosen process should be printed. You basically get the most CPU-heavy and currently active threads, by name. In those cases it’s extremely useful to have custom names.
But how do you set a name? By specifying a named thread factory when creating each executor. Here’s a stackoverflow answer with multiple ways to achieve thread naming.
The method that I’m using is based on the 2nd answer:
public class AsyncUtils {
public static ThreadFactory createNamedThreadFactory(String name) {
return new ThreadFactoryBuilder().setNameFormat(name + "-%d").build();
}
}
Centrally managing all executors through spring might be a better idea, but not everyone is using spring and sometimes an executor is needed for a small piece of functionality that could even go outside spring beans. So it’s a good idea to have that method up your sleeve.
Our software tends to use a lot of thread pools – mostly through java.util.concurrent.ExecutorService
implementations (Created via Executors.new...
. We create these for various async use-cases, and they can be seen all over the place. All of these executors have a thread factory. It’s hidden in the default factory method, but you can supply a thread factory. If not supplied, a default thread factory is used whenever a thread is needed.
When using spring, those can be created using <task:executor />
. In that case, each executor service’s thread factory is provided by spring and it uses the name of the executor bean (specified with id="executorName"
). But for those not created by spring, a default name is used which isn’t helpful and doesn’t let you differentiate threads by name.
And you need to differentiate threads by name – in case of performance issues you have various options to investigate: thread dumps and using the top command. In both cases it’s useful to know what function does a thread service, as the stacktrace in the dump might not always be revealing.
And my favorite tool for quick investigation is top
. More precisely, top -H -p <pid>
. This shows the usual top table, but the -H flag means that threads for the chosen process should be printed. You basically get the most CPU-heavy and currently active threads, by name. In those cases it’s extremely useful to have custom names.
But how do you set a name? By specifying a named thread factory when creating each executor. Here’s a stackoverflow answer with multiple ways to achieve thread naming.
The method that I’m using is based on the 2nd answer:
public class AsyncUtils { public static ThreadFactory createNamedThreadFactory(String name) { return new ThreadFactoryBuilder().setNameFormat(name + "-%d").build(); } }
Centrally managing all executors through spring might be a better idea, but not everyone is using spring and sometimes an executor is needed for a small piece of functionality that could even go outside spring beans. So it’s a good idea to have that method up your sleeve.