Name your threads
Tags: java, threads, troubleshooting, devops
Published: 2021-11-27 21:08:27

---
title: Name your threads
published: true
description: Useful tips about threads in Java
tags: #java #threads #troubleshooting #devops
cover_image: https://cdn.pixabay.com/photo/2020/02/03/00/12/fiber-4814456_1280.jpg
---

A few weeks ago, my team decided to start leveraging [NewRelic JFR](https://docs.newrelic.com/docs/apm/agents/java-agent/features/real-time-profiling-java-using-jfr-metrics/) which is a relatively new feature from NewRelic to provide visibility on [JFR](https://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/about.htm#JFRUH170) events, and I noticed something that got me thinking 🤔

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyp19cbpdn82j9ebglxl.png)

Who the hell is creating all these threads?

By the way, you don't need to use NewRelic or JFR to have a look at your threads. Since JVM threads are actually OS threads, you can also view them with `ps`.

Simply, type `ps -ef` to find the ID of your java process and then `ps -T -p <pid>`.

In my case, it gave me the following output (redacted):

```
  PID  SPID TTY          TIME CMD
    2     2 ?        00:00:00 java
    2     3 ?        00:00:08 java
    2     4 ?        00:10:17 GC Thread#0
                     ...
    2    17 ?        00:10:17 GC Thread#1
    2    34 ?        00:00:01 New Relic Jar A
                     ...
    2    50 ?        00:00:02 pool-3-thread-1
    2    51 ?        00:00:02 redisson-netty-
                     ...
    2    89 ?        00:00:39 pool-5-thread-1
                     ...
    2   109 ?        01:16:09 pool-6-thread-1
```

## Threads everywhere
As our applications grow larger, we start making use of libraries to make external web requests, database queries, etc. Often times, these libraries make use of threads (or thread pools) behind the scenes to improve their throughput. 

![Everywhere](https://c.tenor.com/7Xe1bTiVg6YAAAAC/bb-everywhere.gif)

The JVM assigns threads some default names like the ones we observed above (`Thread-%`, `pool-%-thread-%`). 

Although these names make sense as default values, they are not as helpful when we try to understand if a particular set of threads is misbehaving. 

This could be:
- Allocating too much memory. 
- Taking too much CPU time. 
- Spinning up too many threads (which also has a memory usage impact).
- Deadlocks.

## Name your pets
Mike Wazowski once said: 

![Because once you name it, you get attached to it](https://c.tenor.com/PhCgcyi2tpwAAAAC/mike-wazowski-once-you-name-it-youll-start-getting-attached-to-it.gif)

In this case, I would recommend not to follow his advice and name your 🧵 

This will save you time in the future since you will be able to use effectively many tools that will help you troubleshooting any performance issues.

## How do I do that?
### Threads
If you are the one creating the thread, you can simply do:

```java
thread.setName("boo");
```

### Pools
If you are creating the thread pool, the [`Executors`](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html) class allows you to pass a `ThreadFactory` to its different factory methods.

If you combine that with [Guava's](https://github.com/google/guava) [`ThreadFactoryBuilder`](https://guava.dev/releases/snapshot/api/docs/com/google/common/util/concurrent/ThreadFactoryBuilder.html), you can easily make sure your threads are named with the following:

```java
var factory = 
  new ThreadFactoryBuilder().setNameFormat("boo-%d").build();
var pool = Executors.newFixedThreadPool(1, factory);
```

## Closing words
Once [Project Loom](https://openjdk.java.net/projects/loom/) lands on the SDK, things may change and this advice may not be as useful, since there will no longer be a 1-1 mapping between OS threads and JVM virtual threads.

However, that will take some time to be widely available and even more so to an LTS version (next LTS is planned for [September 2023](https://www.oracle.com/java/technologies/java-se-support-roadmap.html)).

To end, I will go against the pet vs cattle DevOps's mindset and say:

> Treat your threads as pets, not cattle ... for now

![Gru kissing minions](https://media.giphy.com/media/JunL6dl3Xw3ok/giphy.gif)