Java Thread Tutorial - Java Thread Life Cycle








A thread is always in one of the following six states:

  • New
  • Runnable
  • Blocked
  • Waiting
  • Timed-waiting
  • Terminated

All these states of a thread are JVM states.

When a thread is created and its start() method is not yet called, it is in the new state.

Thread  t = new MyThreadClass(); // t is in the   new state

A thread that is ready to run or running is in the runnable state.

A thread is in a blocked state if it is trying to enter or re-enter a synchronized method or block but the monitor is being used by another thread.





State Transition

A thread may place itself in a waiting state by calling the methods listed in the following table.

MethodDescription
wait()from Object class.
join()from the Thread class.
park()from the java.util.concurrent.locks.LockSupport class. A thread that calls this method may wait until a permit is available by calling the unpark() method on a thread.

A thread may place itself in a timed-waiting state by calling methods listed in the following table.

MethodDescription
sleep()from the Thread class.
wait (long millis)
wait(long millis, int nanos)
from the Object class.
join(long millis)
join(long millis, int nanos)
from the Thread class.
parkNanos (long nanos)
parkNanos (Object blocker, long nanos)
from LockSupport class, which is in the java.util.concurrent.locks package.
parkUntil (long deadline)
parkUntil (Object blocker, long nanos)
from the LockSupport class, which is in the java.util.concurrent.locks package.

A thread that has completed its execution is in the terminated state.

A terminated thread cannot transition to any other state.





Example

We can use the isAlive() method of a thread after it has been started to know if it is alive or terminated.

We can use the getState() method from the Thread class to get the state of a thread at any time.

This method returns one of the constants of the Thread.State enum type.

The following code demonstrate the transition of a thread from one state to another.

class ThreadState extends Thread {
  private boolean keepRunning = true;
  private boolean wait = false;
  private Object syncObject = null;
//ww  w  .ja  v  a2 s . c o m
  public ThreadState(Object syncObject) {
    this.syncObject = syncObject;
  }
  public void run() {
    while (keepRunning) {
      synchronized (syncObject) {
        if (wait) {
          try {
            syncObject.wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }
  }

  public void setKeepRunning(boolean keepRunning) {
    this.keepRunning = keepRunning;
  }

  public void setWait(boolean wait) {
    this.wait = wait;
  }
}

public class Main {
  public static void main(String[] args) throws InterruptedException {
    Object syncObject = new Object();
    ThreadState ts = new ThreadState(syncObject);
    System.out.println("Before start()-ts.isAlive():" + ts.isAlive());
    System.out.println("#1:" + ts.getState());

    ts.start();
    System.out.println("After start()-ts.isAlive():" + ts.isAlive());
    System.out.println("#2:" + ts.getState());
    ts.setWait(true);

    Thread.currentThread().sleep(100);

    synchronized (syncObject) {
      System.out.println("#3:" + ts.getState());
      ts.setWait(false);
      syncObject.notifyAll();
    }

    Thread.currentThread().sleep(2000);
    System.out.println("#4:" + ts.getState());
    ts.setKeepRunning(false);

    Thread.currentThread().sleep(2000);
    System.out.println("#5:" + ts.getState());
    System.out.println("At the   end. ts.isAlive():" + ts.isAlive());
  }
}

The code above generates the following result.