The Definitive Guide to Java Threading
Java Multi-Threading Series: Part 1
Learn Java threading in Layman’s terms
This series is about threads in java, from basic to advance topics like the synchronized keyword, atomic wrappers, understanding atomicity and more.
This post will cover a very high level concepts of threading, you will progressively see more code as the series grow.
In order to set the stage for this complex topic, a hello world example will be used, this application does only one thing which is to print “hello, world” to the console.
Before we begin, keep this quote mind from the book “Java 6, Study Guide”
When it comes to thread, very little is guaranteed
- What is a thread and its role
- The main thread
- Thread life cycle
- Thread scheduler
- Thread priorities
What is a thread
In java, threads can mean two things:
- An instance of a class java.lang.Thread
- A thread of execution
From the first point, yes thread is an object, just like any other objects you encounter in programming, it has variable and methods, lives and dies in the heap, just like a Cat object or a Dog object.
In the second point, a thread can be a path of execution, it is an individual process that has its own call stack. For example, when you first start your hello world application, there is a thread executing your main() method, that thread is called the main thread, which is created by the Java Virtual Machine (JVM).
So, in short, threads execute methods
The main thread
A hello world application is deceptively simple, but there are a lot of complexity happening in the background that we should study upon.
You see, the main method is executed by a thread called the main thread and it is created by the JVM at run time.
The sole purpose of a main thread is to execute the
This main thread belongs to a group called “main” thread group, and this group is a child of “system” thread group which contains other threads called daemon threads which does following tasks:
- Finalizer (garbage collector)
- Reference handler
- Signal dispatcher
- Attach listeners
Thread life cycle
Normally, there are four life cycle stages to a thread
- Born/ new state — This is when you create a thread object using the
- Runnable — This is when you execute the start() method (more on this later)
- Running — When the thread scheduler allocate processor to the thread
- Dead state — when the thread returns from the run() method (more on this later)
Born/ New → Runnable → Running → Dead
Here are the key points:
- When we create a thread object using
new Thread(), the object will live in the heap like any other object. This thread is in the born/ new state
- When you call
start()method on a thread, when the method returns, it will be in a runnable state. Why runnable? because it is up to the thread scheduler to actually run the code inside of the
- Once the thread scheduler allocate processing time to the thread, it will be in a running state
- As soon as the thread returns from the
run()method, it will be in a dead state
Therefore, the only way to terminate a thread is to arrange for its
run() method to complete
Here is another quote from “Java 6, Study Guide”
The order in which runnable threads are chosen to run is not guaranteed
The main role of the thread scheduler is to decide which thread should receive processing time from the processor, threads will be queuing up in front of the thread scheduler and the thread scheduler coordinates which thread get the processor time.
The key takeaway is just because the thread scheduler allocated processing time to a thread, it doesn’t guarantee it will complete the execution.
This is known as context switching where the thread scheduler switches from thread to thread, while switching, the thread scheduler will save the current executing state in order to continue once the thread has the opportunity for processing time. Keep in mind the context switching adds performance overhead to your application.
- Thread-1 gets allocated processing time from the thread scheduler
- Context switch happened because thread scheduler decided to give Thread-2 processing time
- Thread-2 is executing,
- Context switched happened again, now Thread-1 is executing and returns from the run() method.
Another analogue to think about thread scheduler:
Have you ever come across an intersection where the traffic light are not working but instead an operator is directing the traffic? you can think of the operator as the thread scheduler and the lanes are the threads.
We set priorities in our daily lives, but sometime just because we set an action item priorities to high, it doesn’t necessary mean they will get done first. Same applies to threads.
Thread priority is an indicator to thread scheduler about the importance or the urgency of a particular thread, the priority level ranges from 1 to 10, 1 being least important and 10 being the most important.
In the threading world, nothing is guaranteed, period. We have the ability to set thread priorities but it does not necessarily mean it will be executed first if there is another thread at a lower priority.
For example, if I ask you this question:
Imagine there two threads, Thread-1 at a default priority of 5 and Thread-2 at a priority of 10. Which thread will receive processing time first?
Intuitively, you will think of course Thread-2 will get processing time because Thread-1 is at a lower priority.
The correct answer should be:
Thread-2 will have a higher probability of executing before Thread-1 because Thread-1 has a lower priority than Thread-2. However, this behavior is not guaranteed.
It is all about probabilities, you cannot predict what the thread scheduler will do because it varies from JVM to JVM. If a thread has a higher priority than another thread, all that means to you is that the thread has a higher probability to executing before the other thread. However, not guaranteed
I hope you enjoyed reading part 1 and understand threading on a top level. In part 2, we will explore the following topics.
- Thread groups
- Daemon threads
- Thread creation
- Inheritance of thread properties
I hope you guys find this valuable, if you learned something, drop a clap! Thank you for reading.