Thread Scheduling is done in JVM by thread scheduler. If multiple threads are waiting to get the chance of execution, then Thread Scheduler decides the order of execution of threads. We can’t predict exact order of thread execution as different JVMs use different scheduling algorithms like Round Robin, First Come First Serve, Shortest Job First etc.
Threads can be executed in mainly two following ways and we will see how they are scheduled in both ways.
1) Thread Scheduling when invoked by thread’s start() method
In Java, the Main function acts like a thread. When we create a thread object and invoke its start() method, this main thread creates another thread and calls its run() method. Order of execution of main thread and child thread is unpredictable as it depends on the scheduling algorithm. We can not predict the order of execution of threads.
Let us understand with the following example.
// We create our own class named MyThread that extends Thread class class MyThread extends Thread { // Overridden run method public void run() { // Child Thread executing and printing one statement 10 times for(int i=1;i<=10;i++) { System.out.println("Child Thread is running"); } } } // Main class public class Demo { public static void main(String args[]) { // Creating two thread objects of our class named MultiThread and starting both the threads concurrently. Thread thread = new MyThread(); thread.start(); // Main Thread executing and printing one statement 10 times for(int i=1;i<=10;i++) { System.out.println("Main Thread is running"); } } }
When we run above code, there will be two threads running concurrently. One will be the main thread and other will be child thread that is created and called by the main thread. When we create an object of MyThread in the main function and call its start() method, main thread creates a separate independent thread and calls its run() function. Thus, two independent threads are executed simultaneously. In this, the order of execution cannot be predicted and both threads will print their statements in any order. Running this program several times gave following different outputs.
Output 1:
Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running
Output 2:
Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running
This shows the unpredictability in the execution order of both threads. This output can come in any other order and we can not expect any specific order. That is why threads are used to reduce CPU time by executing two completely independent tasks simultaneously.
2) Thread Scheduling when invoked by thread’s run() method
We can explicitly call thread’s run() method from the main function and make it run prior to the execution of following tasks in the main function.
Actually, when we call thread’s run() method directly from the main function, main thread does not create any new thread and will itself execute the run() method of that thread. So basically, there is only one thread and hence we can predict the outcome in this case.
// We create our own class named MyThread that extends Thread class class MyThread extends Thread { // Overridden run method public void run() { // Child Thread executing and printing one statement 10 times for(int i=1;i<=10;i++) { System.out.println("Child Thread is running"); } } } // Main class public class Demo { public static void main(String args[]) { // Creating two thread objects of our class named MultiThread and starting both the threads concurrently. Thread thread = new MyThread(); thread.run(); // Main Thread executing and printing one statement 10 times for(int i=1;i<=10;i++) { System.out.println("Main Thread is running"); } } }
Output:
Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Child Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running Main Thread is running