Java Thread State Introduction with Example – Life Cycle of a Thread

Last updated
App Shah

Crunchify » Java and J2EE Tutorials » Java Thread State Introduction with Example – Life Cycle of a Thread

Java Thread State Introduction with Example

Thread States

The following diagram illustrates the various states that a Java thread can be in at any point during its life and which method calls cause a transition to another state. This diagram is not a complete finite state diagram, but rather an overview of the more interesting and common facets of a thread’s life.

You are at right place if you have any of below quesitons:

  • Life Cycle of a Thread in Java
  • Lifecycle and States of a Thread in Java
  • Understanding Java Thread States

The remainder of this page discusses a Thread's life cycle in terms of its state.

Java Thread State with Example

New Thread

The following statement creates a new thread but does not start it thereby leaving the thread in the state labeled New Thread in the diagram.

Thread myThread = new MyThreadClass();

When a thread is in the New Thread state, it is merely an empty Thread object. No system resources have been allocated for it yet. Thus when a thread is in this state, you can only start the thread or stop it; calling any other method besides start() or stop() when a thread is in this state makes no sense and causes an IllegalThreadStateException.


Now consider these two lines of code:

Thread myThread = new MyThreadClass();

The start() method creates the system resources necessary to run the thread, schedules the thread to run, and calls the thread’s run() method. At this point the thread is in the “Runnable” state. This state is called “Runnable” rather than “Running” because the thread may not actually be running when it is in this state. Many computers have a single processor making it impossible to run all “Runnable” threads at the same time.

So, the Java runtime system must implement a scheduling scheme that shares the processor between all “Runnable” threads. However, for most purposes you can think of the “Runnable” state as simply “Running”. When a thread is running–it’s “Runnable” and is the current thread–the instructions in its run() are executing sequentially.

Not Runnable

A thread enters the Not Runnable state when one of these four events occur:

  • someone calls its suspend() method
  • someone calls its sleep() method
  • the thread uses its wait() method to wait on a condition variable
  • the thread is blocking on I/O.

For example, the bold line in this code snippet

Thread myThread = new MyThreadClass();
try {
} catch (InterruptedException e){

puts myThread to sleep for 10 seconds (10,000 milliseconds). During those 10 seconds, even if the processor became available myThread would not run. After the 10 seconds are up, myThread becomes “Runnable” again and now if the processor became available myThread would run.

For each of the “entrances” into the “Not Runnable” state listed above, there is a specific and distinct escape route that returns the thread to the “Runnable” state. An escape route only works for its corresponding “entrance”. For example, if a thread has been put to sleep, then the specified number of milliseconds must elapse before the thread becomes “Runnable” again. Calling resume() on a sleeping thread has no effect.

The following indicates the escape route for every entrance into the “Not Runnable” state.

  • If a thread has been put to sleep, then the specified number of milliseconds must elapse.
  • If a thread has been suspended, then someone must call its resume() method.
  • If a thread is waiting on a condition variable, whatever object owns the variable must relinquish it by calling either notify() or notifyAll().
  • If a thread is blocked on I/O, then the specified I/O command must complete.


A thread can die in two ways: either from natural causes, or by being killed (stopped). A thread dies naturally when its run() method exits normally. For example, the while loop in this method is a finite loop–it will iterate 100 times and then exit.

public void run() {
    int i = 0;
    while (i < 100) {
	System.out.println("i = " + i);

A thread with this run() method will die naturally after the loop and the run() method completes.

You can also kill a thread at any time by calling its stop() method. This code snippet.

Thread myThread = new MyThreadClass();
try {
} catch (InterruptedException e){

creates and starts myThread then puts the current thread to sleep for 10 seconds. When the current thread wakes up, the bold line in the code segment kills myThread.

The stop() method throws a ThreadDeath object at the thread to kill it. Thus when a thread is killed in this manner it dies asynchronously. The thread will die when it actually receives the ThreadDeath exception.


The runtime system throws an IllegalThreadStateException when you call a method on a thread and that thread’s state does not allow for that method call. For example, IllegalThreadStateException is thrown when you call suspend() on a thread that is not “Runnable”.

As shown in the various examples of threads so far in this lesson, when you call a thread method that can throw an exception, you must either catch and handle the exception, or declare that the calling method throws the uncaught exception.

The isAlive() Method

And a final word about thread state: the programming interface for the Thread class includes a method called isAlive(). The isAlive() returns true if the thread has been started and not stopped. Thus, if the isAlive() method returns false you know that the thread is either a “New Thread” or “Dead”.

If the isAlive() method returns true, you know that the thread is either “Runnable” or “Not Runnable”. You cannot differentiate between a “New Thread” and a “Dead” thread; nor can you differentiate between a “Runnable” thread and a “Not Runnable” thread.

While looking at complex thread examples found this really great tutorial on net. Everybody should read this carefully.

6 thoughts on “Java Thread State Introduction with Example – Life Cycle of a Thread”

  1. The producer–consumer problem (also known as the bounded-buffer problem) is a classic example of a multi-process synchronization problem. The problem describes two processes, the producer and the consumer, who share a common, fixed-size buffer used as a queue.

    Learn when and How to Stop the Thread,using jconsole or JvisualVM to indetify is the thread is running.


Leave a Comment