Technology Inside Out!

Index ¦ Archives ¦ Atom ¦ RSS

Java Multithreading : Thread States and Thread Priority

In a thread lifecycle it can  have one of the  following states mentioned below. I have already explained Thread Life Cycle and basics of thread including Daemon Threads.

Now let see inside the thread states and how to achieve them .

  • NEW : A thread has not started yet.
  • RUNNABLE : Thread is running state but it can be in state of waiting.
  • BLOCKED :  Thread is waiting to acquire monitor lock to enter into a synchronized block/method after calling

    Object.wait()

  • WAITING : A thread is in waiting state due to calling one of the following methods
    • Object.wait() : It causes current thread to wait until it been notified by method

       

       

      or 

      notifyAll().

    • Object.join() : Waits for current thread to die.
    • LockSupport.park : Disables the current thread for thread scheduling purposes unless the permit is available.
  • TIMED_WAITING : Current thread is waits for another thread for specified time to perform the aciton.
    • Thread.sleep (long timeInMilliSecond) : Makes current thread to cease the execution for specified time.
    • Object.wait (long timeInMilliSecond) :  Causes current thread to wait for specified time until time elapsed or get notified by

      notify()

      or

      notifyAll()

      .
    • Thread.join (long millis) : Current thread waits for specified time to die the thread.
    • LockSupport.parkNanos (long nanoSeconds) : Disables the current thread for thread scheduling purposes, for up to the specified waiting time, unless the permit is available.
    • LockSupport.parkUntil ()
  • TERMINATED : When thread completed its execution.

Also, how to set Thread Priority

  

NEW, RUNNING and TERMINATED

public class ThreadStates {
  public static void main(String []args) throws Exception{
    MyThreads firstObj =  new MyThreads( 0);
    MyThreads secondObj =  new MyThreads(1000);
    Thread t1 = new Thread(firstObj, "firstThread");
    Thread t2 = new Thread(secondObj, "secondThread");
    System.out.println(t1.getName() +" "+ t1.getState());
    System.out.println(t2.getName() +" "+ t2.getState());
    t1.start();
    t2.start();
    Thread.sleep(2000);
    System.out.println(t1.getName() +" "+ t1.getState());
    System.out.println(t2.getName() +" "+ t2.getState());

  }

}
class MyThreads implements Runnable {

  long sleeptime;
  MyThreads(long sleeptime){
    this.sleeptime = sleeptime;
  }
  @Override
  public void run() {
    for(int i=0; i<=5; i++){
      System.out.println(Thread.currentThread().getName() + " " + i);
      try {
        Thread.sleep(sleeptime);
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      }

    }
  }
}

--- Output--
firstThread NEW
secondThread NEW
secondThread 0
firstThread 0
firstThread 1
firstThread 2
firstThread 3
firstThread 4
firstThread 5
secondThread 1
secondThread 2
firstThread TERMINATED
secondThread TIMED_WAITING (due to Thread.sleep(time) call)
secondThread 3
secondThread 4
secondThread 5

WAITING and

TIMED_WAITING due to

wait()

and

wait(timeGiven) :

When wait() is called on a Thread, it will keep waiting until notified.

While wait(timeGiven), wait until the timeGiven expired or notified.

public class RunWait {
    public static void main(String []args) throws InterruptedException {
        WaitDemo waitDemo = new WaitDemo();
        Thread t = new Thread(waitDemo, "WaitThread");
        t.start();
        Thread.sleep(1000);
        System.out.println(t.getName()+" checking in main() "+t.getState());
        waitDemo.setValue();
    }
}
class WaitDemo implements Runnable{
    private boolean isValueSet = false;

    @Override
    public void run() {
        synchronized(this){
            while(!isValueSet ){
                try {
                    wait();  // Check with wait(1000) for TIMED_WAITING
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }

        System.out.println("Got the Value: "+isValueSet);
    }

    public void setValue(){
        synchronized(this){
            this.isValueSet = true;
            notifyAll();
        }
    }
}

---
Output
WaitThread checking in main() WAITING
Got the Value: true

BLOCKED : When thread is waiting to enter acquire monitor lock or to enter into synchronized method/block  or to enter into Critical Section

public class BlockedDemo {
    public static void main(String []args){
        BlockedThread blockedThread = new BlockedThread(5);

        Thread t1 = new Thread(blockedThread, "t1");
        Thread t2 = new Thread(blockedThread, "t2");

        t1.start();
        t2.start();
        System.out.println(t1.getName() +" " +t1.getState());
        System.out.println(t2.getName() +" " +t2.getState());
    }

}

class BlockedThread implements Runnable {
    private int givenVar;
    BlockedThread(int givenVar){
         this.givenVar = givenVar;
    }
    @Override
    public void run() {
        synchronized (this){
            try {
                Thread.sleep(2000);
                givenVar +=  givenVar;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName()+" changed value "+ givenVar);
    }
}

--------------
Output
t1 TIMED_WAITING
t2 BLOCKED
t1 changed value 10
t2 changed value 20

Observe the output, Thread t2 is in blocked status while t1 is executing. Without synchronized block both thread will read original value of  givenVar (try without synchronized block).

Note: Here two threads are working on single object and synchronized block ensuring that only one thread will enter inside the block. This block also known as Critical section.

WAITING and TIMED_WAITING becuase of

Thread.join()

and

Thread.join(givenTime)

threadX.join() --  It makes calling thread to wait for threadXto finish.

threadX.join(1000) -- Calling thread will be glued to thread threadX for 1000 miliSeconds and resume after this.

public class ThreadJoinDemo {
    public static void main(String []args) throws InterruptedException {
        ThreadJoin threadJoin = new ThreadJoin();
        Thread t = new Thread(threadJoin);

        t.start();
        t.join();
        System.out.println("in main() method");
    }
}

class  ThreadJoin implements Runnable{

    @Override
    public void run() {
        System.out.println("Entered run()");
        int i = 1;
        while(i<5){
            i += i;

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Finished run()");
    }
}

 WAITING due to[ 

LockSupport.park()

: Javadoc]{style="font-family: 'courier new', courier;"}

Methods park and unpark provide efficient means of blocking and unblocking threads and avoids the the Race condition between one thread is parking another is unparking.

Following is simplest program I code to demonstrate this situation to unpark by other thread.

public class NewPark {
    public static void main(String []args) throws InterruptedException {
        FIFOMutex fifoMutex = new FIFOMutex();
        Thread t1 = new Thread(fifoMutex,"t1");
        t1.start();
        Thread.sleep(1000);
        System.out.println(t1.getName() +" "+ t1.getState());
        fifoMutex.unlock(t1);  //unPaking thread t1

    }
}

class FIFOMutex implements Runnable{
     public void lock(){
         System.out.println("Parking Thread "+Thread.currentThread().getName());
         LockSupport.park();
         System.out.println("After unpark "+Thread.currentThread().getName());
     }

    public void unlock(Thread thread) {
        System.out.println("Unparking: "+thread.getName());
        LockSupport.unpark(thread);

    }

    public void run(){
        lock();
    }
}

---
Output:
Parking Thread t1
t1 WAITING
Unparking: t1
After unpark t1

Setting Thread Priority

You can set priority from 1 (lowest) to 10 (highest) by using thread.setPriority(number) or can use Thread.MAX_PRIORITY, Thread.MIN_PRIORITY. By default thread priority set to 5 that is Thread.NORM_PRIORITY.

Setting priority doesn't guarantee to execute higher priority thread to run first. It just hint the scheduler that this thread has high priority but it's depends on scheduler how to queue the threads.

public class ThreadPriority {
    public static void main(String []args) throws InterruptedException {
        PriorityThread priorityThread = new PriorityThread();
        Thread t1 = new Thread(priorityThread, "Thread1");
        Thread t2 = new Thread(priorityThread, "Thread2");
        Thread t3 = new Thread(priorityThread, "Thread3");
        t3.setPriority(Thread.MAX_PRIORITY);
        t2.setPriority(Thread.MIN_PRIORITY);
        t1.setPriority(Thread.NORM_PRIORITY);

        t1.start();
        t2.start();
        t3.start();
    }
}

class PriorityThread implements Runnable {

    @Override
    public void run() {
        for(int i=0; i < 5 ; i++){
            System.out.println(Thread.currentThread().getName() +" "+i);
        }
    }
}

I hope threads states are clear now, Feel free to comment and share.

© The Geeky Way. Built using Pelican. Theme by Giulio Fidente on github.

Disclaimer Privacy policy