Thread prevention deals with how we can prevent a thread from executing on a temporary or permanent basis. We can prevent thread execution by using the 3 methods in Java namely yield, join and sleep method.
Before understanding thread prevention, let’s first understand the life cycle of a thread. Look at the following diagram which is like a state transition diagram explaining thread life cycle.
Let us understand the above diagram.
When we create thread object, it is in new/born state. Calling its start() method moves the thread from new state to runnable state. When its run() method is executed and the thread is allocated processor time, it moves to running state. In the end, when run() method is completely executed, the thread goes into dead state.
Yield method causes the currently executing thread to pause and give the chance for waiting threads of the same priority to execute. Thus, yield() method allows the thread to move from running state to runnable state.
Impact of yield() method on the lifecycle of a thread
If there are no waiting threads or all waiting threads have low priority, then the same thread can continue its execution.
If multiple threads are waiting with the same priority then thread scheduler will decide that which thread will get the first chance to execute.
The thread which is yielded (temporarily paused), when it will get the chance once again, it depends on thread scheduler and we cannot predict exactly.
Child thread always calls yield method. Because of that, the main thread gets chance more number of times and the chance of completing main thread first is high.
Example of Thread Prevention using yield() Method
// We create our own class named MyThread that extends Thread class class MyThread extends Thread { // overridden run method public void run() { for(int i=0;i<10;i++) { System.out.println("Child thread is running"); Thread.yield(); } } } // Main class public class Demo { public static void main(String args[]) { // Creating a thread object of our class named MyThread and starting the thread. MyThread thread = new MyThread(); thread.start(); for(int i=0;i<10;i++) { System.out.println("Main thread is running"); } } }
In above example, child thread iteratively calls yield() in a loop. Hence there are higher chances that child thread will complete its execution before main thread. Following are two different outcomes observed by running this program.
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 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 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
However, some platforms/operating systems don’t provide support for yield method because yield is preemptive scheduling and some processors/platforms only support non-preemptive scheduling.