riven

Riven

Riven

Thread life cycle in java with java

Java’s multithreading capabilities allow developers to create highly concurrent applications. Understanding the thread lifecycle is essential for effectively managing threads and ensuring that your applications perform efficiently and reliably. 

Introduction to Threads

In Java, a thread is a lightweight process that runs concurrently with other threads. Each thread has its own stack and local variables but shares memory with other threads in the same process. The Java Virtual Machine (JVM) manages thread execution, scheduling, and lifecycle.

Benefits of Multithreading

  1. Concurrency: Multiple threads can perform tasks simultaneously, improving application performance.
  2. Responsiveness: Threads help keep applications responsive, particularly in user interfaces, where long-running tasks can be executed in the background.
  3. Resource Sharing: Threads can share data and resources efficiently, facilitating communication between different parts of an application.

The Thread Lifecycle

The lifecycle of a thread in Java consists of several states, each representing a specific stage of a thread’s existence. The primary states are:

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

1. New State

A thread is in the New state when it is created but not yet started. In this state, the thread has not begun its execution.

Example of New State

				
					public class NewStateExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("Thread is running.");
        });
        // Thread is in New state here
        System.out.println("Thread state: " + thread.getState()); // Outputs: NEW
    }
}
				
			

2. Runnable State

A thread enters the Runnable state when the start() method is called. It indicates that the thread is ready to run and waiting for CPU time. A thread in this state may be actively executing or waiting for its turn to execute.

Example of Runnable State

				
					public class RunnableStateExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("Running: " + i);
                try {
                    Thread.sleep(500); // Simulating work
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        thread.start(); // Thread is now in Runnable state
        System.out.println("Thread state after start(): " + thread.getState()); // Outputs: RUNNABLE
    }
}
				
			

3. Blocked State

A thread enters the Blocked state when it is trying to acquire a lock that another thread holds. In this state, the thread cannot proceed until the lock becomes available.

Example of Blocked State

				
					class Resource {
    public synchronized void access() {
        System.out.println(Thread.currentThread().getName() + " is accessing the resource.");
        try {
            Thread.sleep(2000); // Simulate work
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public class BlockedStateExample {
    public static void main(String[] args) {
        Resource resource = new Resource();

        Thread thread1 = new Thread(() -> resource.access());
        Thread thread2 = new Thread(() -> resource.access());

        thread1.start(); // Starts the first thread
        thread2.start(); // Starts the second thread, which will be blocked

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Thread1 state: " + thread1.getState()); // May output: TERMINATED
        System.out.println("Thread2 state: " + thread2.getState()); // Outputs: BLOCKED
    }
}
				
			

4. Waiting State

A thread enters the Waiting state when it is waiting for another thread to perform a specific action, such as notify() or notifyAll(). In this state, the thread is not consuming CPU resources.

Example of Waiting State

				
					class WaitNotifyExample {
    private final Object lock = new Object();
    private boolean condition = false;

    public void await() throws InterruptedException {
        synchronized (lock) {
            while (!condition) {
                lock.wait(); // Thread enters Waiting state
            }
            System.out.println("Condition met, proceeding.");
        }
    }

    public void signal() {
        synchronized (lock) {
            condition = true;
            lock.notify(); // Notifies the waiting thread
        }
    }
}

public class WaitingStateExample {
    public static void main(String[] args) {
        WaitNotifyExample example = new WaitNotifyExample();

        Thread waitingThread = new Thread(() -> {
            try {
                example.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        waitingThread.start();

        try {
            Thread.sleep(1000); // Give waitingThread time to enter Waiting state
            example.signal(); // Notify the waiting thread
            waitingThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Waiting thread state: " + waitingThread.getState()); // Outputs: TERMINATED
    }
}
				
			

5. Timed Waiting State

A thread enters the Timed Waiting state when it calls methods like sleep(millis), wait(millis), or join(millis). The thread will remain in this state for the specified duration or until it is notified.

Example of Timed Waiting State

				
					public class TimedWaitingStateExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(1000); // Thread enters Timed Waiting state
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("Thread is awake.");
        });

        thread.start();

        System.out.println("Thread state after starting: " + thread.getState()); // Outputs: RUNNABLE
        try {
            Thread.sleep(500); // Main thread sleeps for a short time
            System.out.println("Thread state during sleep: " + thread.getState()); // Likely outputs: TIMED_WAITING
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
				
			

6. Terminated State

A thread enters the Terminated state when it has completed execution, either by returning from the run() method or by throwing an unhandled exception. In this state, the thread is no longer alive and cannot be restarted.

Example of Terminated State

				
					public class TerminatedStateExample {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("Thread is running.");
        });

        thread.start(); // Thread is now running
        try {
            thread.join(); // Main thread waits for this thread to finish
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Thread state after completion: " + thread.getState()); // Outputs: TERMINATED
    }
}
				
			

Visualizing the Thread Lifecycle

To summarize, the thread lifecycle can be visualized as follows:

Thread State Methods

Java provides several methods for managing thread states:

  • start(): Transitions a thread from the New state to the Runnable state.
  • run(): Defines the thread’s execution logic. When called directly, it doesn’t start a new thread.
  • sleep(long millis): Puts the thread into the Timed Waiting state for a specified duration.
  • join(): Causes the current thread to wait until the thread on which join() is called terminates.
  • wait(): Causes the current thread to wait until another thread invokes notify() or notifyAll() on the object.
  • notify(): Wakes up a single thread that is waiting on the object’s monitor.
  • notifyAll(): Wakes up all threads that are waiting on the object’s monitor.
  • interrupt(): Interrupts a thread, which can be in any state.

Best Practices for Thread Management

  1. Minimize Shared State: Reduce the number of shared resources to prevent synchronization issues.
  2. Use Thread Pools: Utilize the Executors framework to manage threads more efficiently and avoid overhead from creating new threads.
  3. Handle Exceptions Properly: Always catch and handle exceptions within threads to prevent unexpected termination.
  4. Use Thread-Safe Collections: For sharing data between threads, use collections designed for concurrent access, like ConcurrentHashMap.
  5. Document Thread Behavior: Clearly document how threads interact, what resources they access, and their expected behavior to improve maintainability.

Related topic

Socket programming java
Socket programming java with example Sockets programming in Java provides a way for applications to communicate...
Functional interface in java
What is a Functional Interface in java 8? A functional interface in Java is an interface that contains...
Inversion of control spring
Inversion of control spring with example Inversion of Control (IoC) is a core principle of software engineering...
Vector in java
Vector in java with example In Java, the Vector class is part of the Java Collections Framework and represents...
Threads in java
Threads in java with example Threads are a fundamental concept in programming that enable concurrent...
Java unchecked exception
Unchecked Exception in Java In Java, exceptions are categorized into two main types: checked and unchecked...
Configuration in spring
Configuration in spring Spring configuration refers to the process of setting up beans and their dependencies...
java multilevel inheritance
Java multilevel inheritance Multilevel inheritance is a type of inheritance in which a class (child class)...
iterator in java with example
iterator in java with example An iterator in Java is an object that enables you to traverse a collection,...
Else if statement
Java else if statement The else if statement in Java is a powerful construct that allows for more complex...