Thread Priorities:

  • Every Thread in java has some priority, it may be default priority generated by JVM or customised priority provided by programmer.
  • The valid range of Thread priorities is 1 to 10, where 1 is MIN_PRIORITY and 10 is MAX_PRIORITY Thread class defines the following constants to represent some standard priorities.
    • Thread.MIN_PRIORITY -> 1
    • Thread.NORM_PRIORITY -> 5
    • Thread.MAX_PRIORITY -> 10
  • Thread schedular will use priorities while allocating processor.
  • The Thread which is having highest priority will get chance first.
  • If two Threads having same priority then we can't expect exact execution order. It depends upon Thread schedular.

Thread class defines the following methods to get and set priority of a Thread

public final int getPriority()
public final void setPriority(int p) [allowed values range 1 to 10]

Otherwise RuntimeException : IllegalArgumentException

t.setPriority(7);   //Valid
t.setPriority(17);  //Invalid [IllegalArgumentException]

Default Priority:

The Default priority only for the main Thread is 5. But, for all remaining Threads default priority will be inherited from parent to child i.e., whatever priority parent Thread has the same priority will be there for the child Thread.

class MyThread extends Thread{    
    public static void main(String[] args){
        System.out.println(Thread.currentThread().getPriority()); //5
        //Thread.currentThread().setPriority(17); //IllegalArgumentException
        Thread.currentThread().setPriority(9);
        MyThread t = new MyThread();
        System.out.println(t.getPriority()); //9
    }
}    


MyThread t = new MyThread(); --ParentClass--> Thread
MyThread t = new MyThread(); --ParentThread--> mainThread    


class MyThread extends Thread{
    public void run(){
        for(int i = 0; i < 5; i++){
             System.out.println("Child Thread");
        }
    }
}
class ThreadPriorityDemo{
    public static void main(String[] args){
         MyThread t = new MyThread();
         t.setPriority(10); //[--line-1--]
         t.start();
         for(int i = 0; i < 5; i++){
             System.out.println("Main Thread");
         }
    }
}

If we are commenting line-1, then both main and child threads have the same priority 5. Hence, we can't expect execution order and exact output.
If we are not commenting line-1, then both main Thread has priority 5 and child Thread has priority 10. Hence, child Thread will get chance first followed by main Thread.
In this case Output is
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread

Note: Some platforms won't provide proper support for Thread priorities.

We can prevent a Thread execution by using the following methods.
1. yield()
2. join()
3. sleep()

yield() :

  • yield() method causes to pause current executing Thread to give the chance for remaining waiting Threads of same priority.
  • If there is no waiting Thread or all waiting Threads have low priority then same Thread can continue its execution.
  • If multiple Threads are waiting with same priority, then which waiting Threading will get the chance? we can't expect, it depends on Thread Schedular.
  • The Thread which is yielded, when it will get chance once again, it depends on Thread Schedular and we can't expect exactly.
public static native void yield() 
yieldDiagram

class MyThread extends Thread{
    public void run(){
        for(int i = 0; i < 5; i++){
            System.out.println("Child Thread"); 
            Thread.yield(); //line-1
        }
    }
}
class ThreadYieldDemo{
    public static void main(String[] args){
        MyThread t = new MyThread();
        t.start();
        for(int i = 0; i < 5; i++){
           System.out.println("Main Thread");
        }
    }
}
  • In the above program if we are commenting line-1 then both the Threads will executed simultaneously and we can't expect which Thread will complete first.
  • If we are not commenting line-1 then child Thread always called yield() method because of that main Thread will get chance more number of times and the chance of completing main Thread first is high.

NOTE: Some platforms (OS) won't provide proper support for yield() method.


join() :

  • If a Thread wants to wait until completing some other Thread then we should go for join() method.
  • For example, if a Thread t1 wants to wait until completing Thread t2 then t1 has to call t2.join().
  • If t1 executes t2.join() then immediately t1 will be entered into waiting state until t2 completes.
  • Once t2 completes then t1 can continue its execution.

•   public final void join() throws InterruptedException
•   public final void join(long ms) InterruptedException
•   public final void join(long ms, int ns) InterruptedException

Note: Every join() method throws InterruptedException which is checked Exception. Hence compulsory we should handle this exception either by using try-catch or by throws keyword. Otherwise, we will get compile time error

joinDiagram

Case:1 waiting of main Thread until completing child Thread

class MyThread extends Thread{
    public void run(){
        for(int i = 0; i < 5; i++){
            System.out.println("Seetha Thread");
            try{
                Thread.sleep(2000);
            }
            catch(InterruptedException e){
            }
        }
    }
}
class ThreadJoinDemo{
    public static void main(String[] argsthrows InterruptedException{
        MyThread t = new MyThread();
        t.start();
        t.join(); //line-1 
        for(int i = 0; i < 5; i++){
             System.out.println("Rama Thread");
        }
    }
}
  • If we comment line-1 then both main and Child Threads will be executed simultaneously and we can't expect exact output.
  • If we are not comment line-1 then main Thread calls join() method on child Thread object. Hence main Thread will wait until completing child Thread.

In this case output is
Seetha Thread
Seetha Thread
Seetha Thread
Seetha Thread
Seetha Thread
Rama Thread
Rama Thread
Rama Thread
Rama Thread
Rama Thread

Case 2: Waiting of child Thread until completing main Thread:

class MyThread extends Thread{
    static Thread mt;
    public void run(){ 
        try{
            mt.join();
        }
        catch(InterruptedException e){
        }
        for(int i = 0; i < 5; i++){
             System.out.println("Child Thread");
        }
    }
}
class ThreadJoinDemo{
    public static void main(String[] argsthrows InterruptedException{
        MyThread.mt = Thread.currentThread();
        MyThread t = new MyThread();
        t.start();
        for(int i = 0; i < 5; i++){
             System.out.println("Main Thread");
             Thread.sleep(2000);
        }
    }
}

In the above example, Child Thread calls join() method on main Thread object. Hence Child Thread has to wait until completes main Thread.

In this case output is
Main Thread
Main Thread
Main Thread
Main Thread
Main Thread
Child Thread
Child Thread
Child Thread
Child Thread
Child Thread

Case 3:

If main Thread calls join() method on child Thread object and child Thread calls join() method on main Thread object then both the Threads will wait forever and the program will be structed. (This is something like Deadlock).

Case 4:

If a Thread calls join() method on the same Thread itself then the program will be structed(This is something like deadlock). In this case Thread has to wait infinite amount of time.

class ThreadJoinDemo{
    public static void main(String[] argsthrows InterruptedException{
         Thread.currentThread().join();
    }
}

sleep():

If a Thread don't want to perform any operation for a particular amount of time then we should go for sleep() method.


public static native void sleep(long ms) throws InterruptedException
public static native void sleep(long ms, int ns) throws InterruptedException

Note: Every sleep() methods throws InterruptedException, which is checked Exception. Hence whenever we are using sleep() method compulsory we should handle InterruptedException either by try-catch or throws keyword otherwise we will get compile time error.


sleepDiagram
class ThreadSleepDemo{
    public static void main(String[] argsthrows InterruptedException{
        for(int i = 0; i < 5; i++){
             System.out.println("Slide - " + i);
             Thread.sleep(5000);
        }
    }
}

Output:
Slide - 0
Slide - 1
Slide - 2
Slide - 3
Slide - 4

How a Thread can interrupt another Thread???

A Thread can interrupt a sleeping Thread or waiting Thread by using interrupt() method of Thread class.

Syntax :
public void interrupt()

class MyThread extends Thread{
    public void run(){
        try{
            for(int i = 0; i < 5; i++){
                 System.out.println("Lazy Thread");
                 Thread.sleep(2000);
            }
        }
        catch(InterruptedException e){
            System.out.println("I got interrupted");
        }
    }
}
class ThreadSleepDemo{
    public static void main(String[] argsthrows InterruptedException{
        MyThread t = new MyThread();
        t.start();
        t.interrupt(); //line-1
        System.out.println("End of main Thread");
    }
}

Note: If we comment line-1 then main Thread won't interrupt child Thread. In this case child Thread will execute for loop 5 times.
If we are not commenting line-1 then main Thread interrupts child Thread.

In this case output is
End of main Thread
Lazy Thread
I got interrupted

Note:

  • Whenever we are calling interrupt method if the target Thread is not in sleeping or waiting state then there is no impact of interrupt call immediately. interrupt call will be waited until target Thread entered into sleeping or waiting state.
  • If the target Thread entered into sleeping or waiting state then immediately interrupt call will interrupt target Thread.
  • If the target Thread never entered into sleeping or waiting state in its life time then there is no impact in interrupt call. This is the only case where interrupt call will be wasted.

class MyThread extends Thread{
    public void run(){
        for(int i = 0; i < 5; i++){
             System.out.println("Lazy Thread - " +i);
        }
        System.out.println("Iam entering into sleeping state");
        try{
            Thread.sleep(10000);
        }
        catch(InterruptedException e){
            System.out.println("I got interrupted");
        }
    }
}
class ThreadSleepDemo{
    public static void main(String[] argsthrows InterruptedException{
        MyThread t = new MyThread();
        t.start();
        t.interrupt(); //line-1
        System.out.println("End of main Thread");
    }
}

In the above example interrupt call waited until child Thread completes for loop 10000 times.



property yield() Join() sleep()
purpose if a thread wants to pass its execution to give the chance for remaining Threads of same priority then we should go for yield() a Thread wants to wait until completing some other Thread then we should go for join() if a Thread wants to perform any operation for a particular amount of time then we should go for sleep()
is it overloaded NO YES YES
is it final method NO YES NO
is it throws IE NO YES YES
is it native YES NO sleep(long ms) -- native
sleep(long ms, int ns)