This Java Thread tutorial helps you understand the life cycle of a thread with illustrated diagram and code example.

A thread can go through various states during its life. The Thread’s getState() method returns an enum constant that indicates current state of the thread, which falls in one of the following values:

- RUNNABLE

- BLOCKED

- WAITING

- TIMED_WAITING

- TERMINATED

These enum constants are defined in the Thread.State enum. Let me explain each state in details.

  • NEW: when a thread is created but has not executed (the start() method has not been invoked), it is in the new state.
 

  • RUNNABLE: when the start() method has been invoked, the thread enters the runnable state, and its run() method is executing. Note that the thread can come back to runnable state from another state (waiting, blocked), but it may not be picked immediately by the thread scheduler, hence the term “runnable”, not running.
 

  • BLOCKED: when a thread tries to acquire an intrinsic lock (not a lock in the java.util.concurrent package) that is currently held by another thread, it becomes blocked. When all other threads have relinquished the lock and the thread scheduler has allowed this thread to hold the lock, the thread becomes unblocked and enters the runnable state.
 

  • WAITING: a thread enters this state if it waits to be notified by another thread, which is the result of calling Object.wait() or Thread.join(). The thread also enters waiting state if it waits for a Lock or Condition in the java.util.concurrent package. When another thread calls Object‘s notify()/notifyAll() or Condition’s signal()/signalAll(), the thread comes back to the runnable state.
 

  • TIMED_WAITING: a thread enters this state if a method with timeout parameter is called: sleep(), wait(), join(), Lock.tryLock() and Condition.await(). The thread exits this state if the timeout expires or the appropriate notification has been received.
 

  • TERMINATED: a thread enters terminated state when it has completed execution. The thread terminates for one of two reasons:
                + the run() method exits normally.



                + the run() method exits abruptly due to a uncaught exception occurs.

The following diagram helps you visually understand the thread states and transitions between them:

thread-states

And the following code example illustrates how to check state of a thread:

public class ThreadState {

	public static void main(String[] args) throws InterruptedException {
		Thread t = new Thread(new Runnable() {
			public void run() {
				Thread self = Thread.currentThread();
				System.out.println(self.getName() + "is " + self.getState());// LINE 0
			}
		});

		System.out.println(t.getName() + "is " + t.getState()); // LINE 1

		t.start();

		t.join();

		if (t.getState() == Thread.State.TERMINATED) {
			System.out.println(t.getName() + " is terminated"); // LINE 2
		}
	}
}
Run this program and you will see the following output:

Thread-0 is NEW
Thread-0 is RUNNABLE
Thread-0 is terminated
 

Line 1 prints Thread-0 is NEW because at this time the thread t has not been started.

When the thread started, its run method execute, hence line 0 prints Thread-0 is RUNNABLE.

The call t.join() causes the main thread to wait for the thread t to finish, hence line 2 is always executed after thread t completes, thus the output Thread-0 is terminated.

Note that the thread’s state may change after the call to getState(). That means calling getState()  may not reflect the actual state of the thread only a moment later.

 

API References:

 

Related Java Thread Tutorials:

 

Other Java Concurrency Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Add comment

   


Comments 

#2Nam2019-12-05 20:22
Quoting Navneet:
Without calling t.start(), how does state printed as RUNNABLE

Look at the code example again, the line that prints RUNNABLE is in the run() method of the Thread, which is executed after t.start() call.
Quote
#1Navneet2019-12-05 10:30
Without calling t.start(), how does state printed as RUNNABLE
Quote