Introduction to Java threads
Processes and Threads are basic building blocks for concurrent programming. A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space.
Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process. Threads exist within a process every process has at least one. Threads share the process’s resources, including memory and open files.
Every application has at least one thread or several, if you count “system” threads that do things like memory management and signal handling. But from the application programmer’s point of view, you start with just one thread, called the main thread. This thread has the ability to create additional threads.
JVM Thread Dump – what is it?
As the name suggests thread dump is a dump of all the threads in a Java virtual machine. In other words, it is snapshot of current state of all the Java threads running on JVM.
Thread dump contains the current execution state of both application and the JVM specific threads. A thread dump is just a collection of stack traces, one for each thread that’s running in the instance.
Java Code to Generate Thread Dump
package com.ashok.threads; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; public class ThreadDump { public static void main(String[] args) { StringBuilder dump = new StringBuilder(); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); ThreadInfo[] threadInfos = threadMXBean .getThreadInfo(threadMXBean.getAllThreadIds(), 1000); for (ThreadInfo threadInfo : threadInfos) { dump.append('"'); dump.append(threadInfo.getThreadName()); dump.append("\" "); final Thread.State state = threadInfo.getThreadState(); dump.append("\n java.lang.Thread.State: "); dump.append(state); StackTraceElement[] stackTraceElements = threadInfo.getStackTrace(); for (StackTraceElement stackTraceElement : stackTraceElements) { dump.append("\n at "); dump.append(stackTraceElement); } dump.append("\n\n"); } System.out.println(dump); } }
Output
"Attach Listener" java.lang.Thread.State: RUNNABLE "Signal Dispatcher" java.lang.Thread.State: RUNNABLE "Finalizer" java.lang.Thread.State: WAITING at java.lang.Object.wait(Native Method) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) "Reference Handler" java.lang.Thread.State: WAITING at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "main" java.lang.Thread.State: RUNNABLE at sun.management.ThreadImpl.getThreadInfo1(Native Method) at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:178) at com.ashok.threads.ThreadDump.main(ThreadDump.java:11)
Each individual Java Thread found gives you information such as:
1. Thread name
Used by middle ware vendors to identify the Thread Id along with its associated Thread Pool name and state (running, waiting etc.). When using Java.lang.Thread class to generate a thread, the thread will be named Thread-(Number), whereas when using java.util.concurrent.ThreadFactory class, it will be named pool-(number)-thread-(number).
2. Thread type & priority
E.g: daemon prio=6
There are two types of threads in Java i.e.
1. User Thread: This thread is created by user program. They are high priority threads.
E.g. Main thread.
2. Daemon Thread: This is JVM itself generated thread. These threads always run in background. These threads are used to perform some background tasks like garbage collection and house-keeping tasks. These threads are less priority threads.
Example of this thread is Thread Scheduler and Garbage Collector.
Priority represents the priority of the threads.
3. Java Thread ID
E.g: tid=0x000000011e52a800
Represents the unique ID for the threads. This is the Java Thread Id obtained via java.lang.Thread.getId() and usually implemented as an auto-incrementing long 1..n
4. Native Thread ID
E.g: nid=0x251c
Crucial information as this native Thread Id allows you to correlate for example which Threads from an OS perspective are using the most CPU within your JVM etc.
5. Java Thread State and detail ex
Provides the current thread state. A thread can be in one of the following states
1. NEW
Once we created a Thread object then the Thread is said to be in new state or born state. The thread has not yet started to run when thread is in this state. When a thread lies in the new state, it’s code is yet to be run and hasn’t started to execute.
2. RUNNABLE
Once we call start() method then the Thread will be entered into Ready or Runnable state. A thread that is ready to run is moved to runnable state. In this state, a thread might actually be running or it might be ready run at any instant of time. It is the responsibility of the thread scheduler to give the thread, time to run.
A multi-threaded program allocates a fixed amount of time to each individual thread. Each and every thread runs for a short while and then pauses and relinquishes the CPU to another thread, so that other threads can get a chance to run. When this happens, all such threads that are ready to run, waiting for the CPU and the currently running thread lies in runnable state.
3. BLOCKED
The BLOCKED thread is waiting for other thread to release the lock. In the BLOCKED state, a thread is about to enter a synchronized block, but there is another thread currently running inside a synchronized block on the same object. The BLOCKED thread can’t be interrupted.
Real-life example
Today you are going for a job interview. This is your dream job, which you have been targeting for last few years. You woke up early in the morning, got ready, put on your best outfit, looking sharp in front of the mirror.
Now you step out to your garage and realize that your wife has already taken the car. In this scenario, you only have one car, so what will happen? In real life, a fight may happen. However, you are BLOCKED because your wife has already taken the car. You won’t be able to go to the interview.
This is the BLOCKED state. Explaining it in technical terms, you are the thread T1 and your wife is the thread T2 and lock is the car. T1 is BLOCKED on the lock (i.e. the car) because T2 has already acquired this lock.
4. WAITING
A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
Real-life example
Let’s say a few minutes later your wife comes back home with the car. Now you realize that the interview time is approaching, and there is a long distance to drive to get there. So, you put all the power on the gas pedal in the car. You drive at 100 mph when the allowed speed limit is only 60 mph.
Your luck, a traffic cop sees you driving over the speed limit, and he pulls you over to the curb. Now you are entering into the WAITING state, my friend. You stop driving the car and sit idly in the car until the cop investigates you and then lets you go. Basically, until he lets you go, you are stuck in the WAITING state.
This is the WAITING state. Explaining it in technical terms, you are thread T1 and the cop is thread T2. You released your lock (i.e. you stopped driving the car) and went into the WAITING state. Until the cop (i.e. T2) lets you go, you will be stuck in this WAITING state.
5. TIMED_WAITING
A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.”
Real-life example
Despite all the drama, you did extremely well in the interview, impressed everyone and got this high paying job. (Congratulations!) You come back home and tell your neighbor about this new job and how excited you are about it. Your friend says that he is also working in the same office building. He suggests that the two of you should drive together. You think it’s a great idea.
So on the first day of work, you go to his house. You stop your car in front of his house. You wait for 10 minutes, but your neighbor still doesn’t come out. You go ahead and start driving to work, as you don’t want to be delayed on your first day. Now this is TIMED_WAITING.
Explaining it in technical terms, you are thread T1, and your neighbor is thread T2. You release the lock (i.e. stop driving the car) and wait up to 10 minutes. If your neighbor, T2, doesn’t come out in 10 minutes, you start driving the car again.
6. TERMINATED
Thread state for a terminated thread. The thread has completed execution.
6. Java Thread Stack Trace
Java Thread Stack Trace is the most important data that you will find from the Thread Dump. The stack trace is very useful while debugging or troubleshooting any issue in Java. This is also where you will spent most of your analysis time since the Java Stack Trace provides you with 90% of the information that you need in order to pinpoint root cause of many problem pattern types as you will learn later in the training sessions
7. Java Heap breakdown
Starting with HotSpot VM 1.6, you will also find at the bottom of the Thread Dump snapshot a breakdown of the HotSpot memory spaces utilization such as your Java Heap (YoungGen, OldGen) & PermGen space. This is quite useful when excessive GC is suspected as a possible root cause so you can do out-of-the-box correlation with Thread data / patterns found.