For me, studying them allowed me to see code in a different way, at a lower level than just seeing the code line by line, it gave me in-depth insight to what the code is doing, especially preventing out of memory exceptions or the infamous memory leak problem.
Before we begin, keep this quote mind from the book “Java 6, Study Guide”When it comes to thread, very little is guaranteedAgenda:Understand what is a thread and its roleUnderstanding the main threadUnderstanding the thread life-cycleUnderstanding thread schedulerUnderstand thread prioritiesUnderstand what is a thread and its roleA thread a nothing but a path of execution.
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).
The job of a thread is to execute your methods, when you execute a method, a thread is reading the method line by line and giving it to the processor.
So method execution = threads in action, this would be more apparent if you enter debugging mode of any IDE.
Understanding the main threadWhen you start your hello world application, think about what is happening in the background.
Although, a hello world app is deceptively simple, but there are a lot of complexity we can study upon.
You see, the main method and executed by a thread called the main thread and it is created by the JVM at run time, so you don’t create the main thread, JVM does.
This main thread belongs to a thread group called “main” thread group, and this main group is a child of “system” thread group which contains other threads called daemon threads, which we will discuss later on, but simply put, here are the few system level threads:Finalizer (garbage collector)Reference handlerSignal dispatcherAttach listenersSo, we understand main thread lives inside of the main thread group, but how that related to thread creation?We will discuss more on this in-depth later on in part 2Understanding the thread life-cycleNormally, there are four stages to a threadBorn/ new state — This is when you create a thread objectRunnable — This is when you execute the start() method (more on this later)Running — When the thread scheduler allocate processor to the threadDead state — when the thread returns from the run() method (more on this later)Born/ New → Runnable → Running → DeadWe will have an in-depth discussion of this life-cycle later on and there are more states involved, but for simplicity sake, this is enough for now.
Understanding thread schedulerHere is another quote from “Java 6, Study Guide”The order in which runnable threads are chosen to run is not guaranteedThe 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 schedulerContext switch happened because thread scheduler decided to give Thread-2 processing timeThread-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.
Understanding thread prioritiesWe 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-1 will get processing time because Thread-2 is at a lower priority, wrong answer.
The correct answer should be:Thread-1 will have a higher probability of executing before Thread-2 because Thread-2 has a lower priority than Thread-1.
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 guaranteedI hope you enjoyed reading part 1 and understand threading on a top level.
In part 2, we will explore the following topics.
Part 2 will cover:Understanding Thread groupsUnderstanding thread creationUnderstanding run() and start() methodsThank you for reading.