Java - Thread states

[Updated: May 24, 2017, Created: May 23, 2017]

A Java thread can be in one of the several states during it's life time. We can get the state by using Thread class method:

public Thread.State getState()

Thread.State enum has following constants:

NEW: Thread has not yet started.
RUNNABLE: Thread is currently running without blocking/waiting in its run method.
BLOCKED: Thread is blocked from entering a synchronized block/method, waiting for the monitor lock to be released by the other thread.
WAITING: Thread is waiting due to one of the these calls; Object.wait(), Thread.join() or LockSupport.park()
TIMED_WAITING: Thread is waiting due to one of these timeout based method calls; Thread.sleep(long millis), Object.wait(long millis), Thread.join(long millis), LockSupport.parkNanos(Object blocker, long nanos) or LockSupport.parkUntil(Object blocker, long nanos)
TERMINATED: A thread has exited from its run() method.

Note that, using Thread.getState() is not very reliable to make decisions in controlling the threads. It should only be used for testing, monitoring or debugging purpose.

In following examples, we are going to create conditions to see how a given thread can be in one of the defined states.

NEW, RUNNABLE, TERMINATED example

public class Example1 {
    public static void main(String[] args) {
        MyTask t = new MyTask();
        t.setName("Thread1");
        runExampleThread(t);
    }

    static void runExampleThread(Thread t) {
        printState("thread before start()", t);
        t.start();
        printState("thread start() called", t);
        printState("main thread sleeping for 1/2 sec", t);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        printState("main thread woke up", t);

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            printState("shutting down", t);
        }));
    }

    static void printState(String msg, Thread t) {
        System.out.printf("%s - %s state: %s%n", msg, t.getName(),
                t.getState());
    }

    private static class MyTask extends Thread {

        @Override
        public void run() {
            printState("thread run() started", this);
            //doing something
            for (int i = 0; i < 100; i++) {
                Math.random();
            }
            printState("thread is finishing", this);
        }
    }
}

Output

thread before start() - Thread1 state: NEW
thread start() called - Thread1 state: RUNNABLE
main thread sleeping for 1/2 sec - Thread1 state: RUNNABLE
thread run() started - Thread1 state: RUNNABLE
thread is finishing - Thread1 state: RUNNABLE
main thread woke up - Thread1 state: TERMINATED
shutting down - Thread1 state: TERMINATED

TIMED_WAITING example

In this example we are going to use Thread.sleep(millis) method to put the thread into TIME_WAITING state.

Note that, we are going to reuse example code from our first example, so don't be puzzled, when you see a static call like Example1.xyz()

public class Example2 {
    public static void main(String[] args) {
        MyTask2 t = new MyTask2();
        t.setName("Thread2");
        Example1.runExampleThread(t);
    }

    private static class MyTask2 extends Thread {
        @Override
        public void run() {
            Example1.printState("thread run() started", this);
            try {
                //this will put the thread in TIMED_WAITING state
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Example1.printState("thread finishing", this);
        }
    }
}

Output

thread before start() - Thread2 state: NEW
thread start() called - Thread2 state: RUNNABLE
main thread sleeping for 1/2 sec - Thread2 state: RUNNABLE
thread run() started - Thread2 state: RUNNABLE
main thread woke up - Thread2 state: TIMED_WAITING
thread finishing - Thread2 state: RUNNABLE
shutting down - Thread2 state: TERMINATED

WAITING example

In this example we are going to use Object.wait() method to put the thread into WAITING state.

public class Example3 {

    public static void main(String[] args) throws InterruptedException {
        MyTask3 t = new MyTask3();
        t.setName("Thread3");
        Example1.runExampleThread(t);
        synchronized (Example3.class) {
            Example3.class.notifyAll();
        }
    }

    private static class MyTask3 extends Thread {

        @Override
        public void run() {
            Example1.printState("thread run() started", this);
            //using Example3.class object monitor
            synchronized (Example3.class) {
                try {
                    //this will put the thread in WAITING state
                    Example3.class.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Example1.printState("thread finishing", this);
        }
    }
}

Output

thread before start() - Thread3 state: NEW
thread start() called - Thread3 state: RUNNABLE
main thread sleeping for 1/2 sec - Thread3 state: RUNNABLE
thread run() started - Thread3 state: RUNNABLE
main thread woke up - Thread3 state: WAITING
thread finishing - Thread3 state: RUNNABLE
shutting down - Thread3 state: TERMINATED

BLOCKED example

If a thread is waiting for a monitor lock then it will be in BLOCKED state. In following example, we are using Example4.class object as lock for the synchronized blocks. A first thread acquires the lock so that our target thread will be blocked for some time.

public class Example4 {

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            //acquiring lock on Example4.class object
            synchronized (Example4.class) {
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        MyTask4 t = new MyTask4();
        t.setName("Thread4");
        Example1.runExampleThread(t);
    }

    private static class MyTask4 extends Thread {
        @Override
        public void run() {
            Example1.printState("attempting to enter synchronized block", this);
            synchronized (Example4.class) {
                Example1.printState("entered synchronized block", this);
                //do something
            }
            Example1.printState("thread finishing", this);
        }
    }
}

Output

thread before start() - Thread4 state: NEW
thread start() called - Thread4 state: RUNNABLE
main thread sleeping for 1/2 sec - Thread4 state: RUNNABLE
attempting to enter synchronized block - Thread4 state: RUNNABLE
main thread woke up - Thread4 state: BLOCKED
entered synchronized block - Thread4 state: RUNNABLE
thread finishing - Thread4 state: RUNNABLE
shutting down - Thread4 state: TERMINATED

Example Project

Dependencies and Technologies Used :

  • JDK 1.8
  • Maven 3.3.9

Thread States Examples Select All Download
  • java-thread-states
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also