Thread Lifecycle in Java

Table of Contents

In Java, threads are an important part of concurrent programming. A thread is an independent path of execution within a program that can perform tasks concurrently with other threads. Understanding the lifecycle of a thread in Java is crucial for writing efficient and reliable concurrent programs.

The lifecycle of a thread in Java consists of several stages, which are controlled by the Java Virtual Machine (JVM) and the thread scheduler. These stages are:

  1. New
  2. Runnable
  3. Running
  4. Waiting
  5. Timed Waiting
  6. Blocked
  7. Terminated

Let’s take a closer look at each stage of the lifecycle of a thread in Java.

New

The first stage of the lifecycle of a thread in Java is the New stage. In this stage, a thread is created but not yet started. To create a new thread in Java, you can extend the Thread class or implement the Runnable interface. Here’s an example of creating a new thread using the Thread class:

Java
Thread thread = new Thread() {
    public void run() {
        // thread code here
    }
};

In this example, we create a new Thread object and override the run() method with our thread code. However, the thread is still in the New stage and has not yet started.

Runnable

The next stage of the lifecycle of a thread in Java is the Runnable stage. In this stage, a thread is ready to run but not yet running. To start a thread and move it to the Runnable stage, you can call the start() method on the Thread object. Here’s an example:

Java
Thread thread = new Thread() {
    public void run() {
        // thread code here
    }
};

thread.start();

In this example, we create a new Thread object and call the start() method to start the thread. The thread is now in the Runnable stage and ready to run, but the thread scheduler has not yet selected it to run.

Running

The next stage of the lifecycle of a thread in Java is the Running stage. In this stage, a thread is actively executing code. The thread scheduler has selected the thread to run and it is currently running. Here’s an example:

Java
Thread thread = new Thread() {
    public void run() {
        // thread code here
    }
};

thread.start();

// do some other work here

// wait for the thread to finish
thread.join();

In this example, we create a new Thread object, start the thread, and then wait for it to finish using the join() method. The thread is now in the Running stage and executing its code.

Waiting

The next stage of the lifecycle of a thread in Java is the Waiting stage. In this stage, a thread is waiting for a certain condition to occur. To move a thread to the Waiting stage, you can call the wait() method on an object. Here’s an example:

Java
Object lock = new Object();

Thread thread = new Thread() {
    public void run() {
        synchronized(lock) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
};

thread.start();

// do some other work here

// notify the waiting thread
synchronized(lock) {
    lock.notify();
}

In this example, we create a new Thread object, synchronize on an object called lock, and then call the wait() method on the lock object. The thread is now in the Waiting stage and waiting for a notification from another thread. We then notify the waiting thread using the notify() method.

Timed Waiting

The next stage of the lifecycle of a thread in Java is the Timed Waiting stage. In this stage, a thread is waiting for a certain condition to occur, but only for a specified amount of time. To move a thread to the Timed Waiting stage, you can call the sleep() method or the wait() method with a timeout parameter. Here’s an example:

Java
Object lock = new Object();

Thread thread = new Thread() {
    public void run() {
        synchronized(lock) {
            try {
                lock.wait(5000); // wait for 5 seconds
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
};

thread.start();

// do some other work here

// notify the waiting thread
synchronized(lock) {
    lock.notify();
}

In this example, we create a new Thread object, synchronize on an object called lock, and then call the wait() method on the lock object with a timeout of 5000 milliseconds (5 seconds). The thread is now in the Timed Waiting stage and will wait for 5 seconds before continuing. We then notify the waiting thread using the notify() method.

Blocked

The next stage of the lifecycle of a thread in Java is the Blocked stage. In this stage, a thread is blocked waiting for a lock to be released. To move a thread to the Blocked stage, you can try to enter a synchronized block or method that is currently being held by another thread. Here’s an example:

Java
Object lock = new Object();

Thread thread1 = new Thread() {
    public void run() {
        synchronized(lock) {
            // do some work here
        }
    }
};

Thread thread2 = new Thread() {
    public void run() {
        synchronized(lock) {
            // do some work here
        }
    }
};

thread1.start();
thread2.start();

In this example, we create two Thread objects, both of which synchronize on the same object called lock. When thread1 enters the synchronized block, it holds the lock and thread2 cannot enter the same block until thread1 releases the lock. The thread that is waiting for the lock to be released is now in the Blocked stage.

Terminated

The final stage of the lifecycle of a thread in Java is the Terminated stage. In this stage, a thread has completed its execution and has terminated. Here’s an example:

Java
Thread thread = new Thread() {
    public void run() {
        // thread code here
    }
};

thread.start();

// do some other work here

// wait for the thread to finish
thread.join();

if (thread.getState() == Thread.State.TERMINATED) {
    System.out.println("Thread has terminated.");
}

In this example, we create a new Thread object, start the thread, wait for it to finish using the join() method, and then check its state using the getState() method. If the thread’s state is TERMINATED, we print a message indicating that the thread has terminated.

In conclusion, understanding the lifecycle of a thread in Java is crucial for writing efficient and reliable concurrent programs. By understanding the different stages of the lifecycle of a thread, you can better control the behavior of your threads and avoid common pitfalls in concurrent programming. Remember that the JVM and the thread scheduler control the lifecycle of a thread, but the behavior of a thread can also be affected by the code written by the developer.

Command PATH Security in Go

Command PATH Security in Go

In the realm of software development, security is paramount. Whether you’re building a small utility or a large-scale application, ensuring that your code is robust

Read More »
Undefined vs Null in JavaScript

Undefined vs Null in JavaScript

JavaScript, as a dynamically-typed language, provides two distinct primitive values to represent the absence of a meaningful value: undefined and null. Although they might seem

Read More »