In java based applications, Threads form the basic part of every operation. In fact, threads are the very core in most of the processing units in the entire world of computers. As per theoretical definition, threads are lightweight processes that execute tasks assigned to them. But to explain in simpler terminologies, imagine you go to a bank and there is a queue of 10 people waiting (maintaining physical distancing :) ) to perform an action like open an account or withdraw or deposit or do other activities. Imagine there being 5 counters and 1 operator at each counter. This is what the bank counters would look like.
The first customer goes to the first counter, the second customer goes to the second counter, and so on till the fifth customer. The sixth customer however is still waiting in the queue. If any of the first 5 customers finish their activities, the counter gets vacated and the 6th customer can go to that counter. The 7th customer can go to the next vacated counter and so on.
Very similarly, threads are processed in a queue. The threads are picked up by the OS (Thread scheduling) per the priority and handed to the CPU for execution. As we are looking at an example of a Java application, it can have multiple threads in different states. Although each thread can only be in a single state at any given point.
If your JVM is utilizing CPU higher than usual or if you are working on a library that deals with a lot of thread operations or if your application is having deadlocks or even longer response time due to locks, thread dumps can come very handy for debugging. Also, part of scaling java based applications requires us to analyze what threads are doing at a given time under load conditions. Analyzing this can be done using a lot of tools like New Relic, Prometheus, etc. It could also need an analysis of a thread dump. You can get a thread dump of a java application using Java VisualVM or few other monitoring tools. But all the tools internally use the jstack command exposed by the JVM to take a thread dump. So effectively, you can take a thread dump from a terminal or command prompt.
Command to take a thread dump - jstack -l <pid> > dump1.txt
where pid is the process id of your java application (which can be got from the jps command)
Taking a single thread dump is not going to reveal a lot of information as it gives a snapshot or a point in time information of what all the threads in the JVM are doing. What we really need is at least 2 thread dumps taken over a brief duration. We can then compare the state of threads and check if they are stuck in a single operation for a prolonged period.
Analyzing Thread Dumps
A thread dump can be analyzed using multiple tools. There are many online thread dump analyzers like https://fastthread.io/ or https://spotify.github.io/threaddump-analyzer/ but what I personally prefer which also comes very handy is to analyze it in your IDE. A lot of IDEs like Intellij and Eclipse provide plugins that help analyze thread dumps very easily.
I'm going to focus on my favorite IDE Intellij. If you have upgraded to Intellij IDEA 2020 or above, you will see this option Analyze > Stack Trace or Thread Dump
When you paste the thread dump in this section, Intellij IDEA will analyze the thread dump and show you a consolidated summary of threads in various states. You could also include multiple such thread dumps and analyze them in one view.
Online thread dump analyzers even go a step ahead and show potential deadlocks or blocked calls. You can play around with this for some applications even in your local so that you guys can feel more comfortable with this when a situation asks for it. If you have questions as you try this, please do drop your comments below.