Thread concept and life cycle of thread.
Thread concept and life cycle of thread.
Thread Concept
A thread is a lightweight subprocess and the smallest unit of processing in a program.
It operates as a separate path of execution within the program.
Threads are independent of each other. If one thread encounters an exception or error, it does not impact the execution of other threads. Threads share a common memory area, allowing them to efficiently communicate and coordinate their activities
OS
As depicted in the figure above, a thread operates within a process.
Within a single process, threads can switch between execution contexts, enabling concurrent execution of multiple threads.
It's important to note that an operating system can host multiple processes, and each of these processes can contain multiple threads. This structure allows for the efficient utilization of system resources and parallel execution of tasks within and between processes
The Main Thread
You can obtain a reference to the currently executing thread by using the currentThread() method.
To modify the internal name of a thread, you can utilize the setName() method.
To introduce a pause or delay in a thread's execution, you can use the sleep() method. The duration of the pause is determined by the argument provided to sleep(), which specifies the delay period in milliseconds.
It's important to note that when using the sleep() method in the Thread class, it may potentially throw an InterruptedException. This exception occurs if another thread requests the interruption of the sleeping thread while it is in the sleeping state.
Java Thread class
Java offers the Thread class as a fundamental tool for thread programming, supplying constructors and methods for thread management. The Thread class is an extension of the Object class and implements the Runnable interface, enabling the creation and execution of threads with ease.
The concept and life cycle of threads
In Java, a thread always exists in one and only one of the following states at any given moment. It does not occupy multiple states simultaneously.
New
Active
Blocked / Waiting
Timed Waiting
Terminated
The diagram below illustrates the different states a thread can be in at a particular moment in time.
Life Cycle of a Thred
Life Cycle of a Thread
The life cycle of a thread in Java represents the various states through which a thread passes during its execution. Here's a more detailed explanation of the life cycle of a Java thread:
New Thread (New State): When a new thread is created, it enters the "new" state. In this state, the thread's code hasn't started executing, and it's awaiting its turn to run.
Runnable State: Threads in the "runnable" state are ready to run but may or may not be currently executing. The thread scheduler decides when each thread gets CPU time. In a multi-threaded program, threads take turns running for a short duration before giving way to others.
Blocked State: Threads enter the "blocked" state when they attempt to acquire a lock currently held by another thread. They remain blocked until they successfully acquire the lock, at which point they return to the "runnable" state.
Waiting State: Threads can enter the "waiting" state when they call methods like wait() or join(). They stay in this state until another thread notifies them or the waiting thread is terminated.
Timed Waiting State: Threads in the "timed waiting" state are waiting for a specified period or until they receive a notification. This state is entered when a thread calls methods with a time-out parameter, such as sleep() or a conditional wait.
Terminated State: Threads can terminate for two main reasons:
They exit normally after completing their code execution.
They encounter unusual errors, like unhandled exceptions or segmentation faults, leading to unexpected termination.
Java, you can use the Thread.getState() method to get the current state of a thread. The java.lang.Thread.State class defines the ENUM constants that represent the states of a thread. Here's a summary of the Thread.State constants:
Thread.State.NEW: Represents that the thread has been created but has not yet started.
Thread.State.RUNNABLE: Represents that the thread is eligible to run and may be running or waiting for its turn to execute.
Thread.State.BLOCKED: Represents that the thread is blocked, waiting for a monitor lock to enter a synchronized block or method.
Thread.State.WAITING: Represents that the thread is waiting for another thread to perform a particular action.
Thread.State.TIMED_WAITING: Represents that the thread is waiting for a specified amount of time.
Thread.State.TERMINATED: Represents that the thread has finished its execution or has been explicitly stopped.
You can use these `Thread.State` constants along with the `Thread.getState()` method to monitor and manage the state of threads in your Java programs.
Sample code to create Threads by Extending Thread Class
public class ThreadExample extends Thread {
public void run() {
// Code to be executed by the thread
for (int i = 1; i <= 5; i++) {
System.out.println("Thread: " + i);
}
}
public static void main(String[] args) {
ThreadExample thread1 = new ThreadExample();
ThreadExample thread2 = new ThreadExample();
// Start the threads
thread1.start();
thread2.start();
// Code in the main thread
for (int i = 1; i <= 5; i++) {
System.out.println("Main: " + i);
}
}
}
Output:-
Thread: 1
Thread: 1
Main: 1
Thread: 2
Main: 2
Thread: 3
Main: 3
Thread: 4
Main: 4
Thread: 5
Main: 5
Thread: 2
Java Program to explore different Thread States:-
public class ThreadStateExample {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new MyRunnable(), "Thread 1");
Thread thread2 = new Thread(new MyRunnable(), "Thread 2");
System.out.println(thread1.getName() + " state: " + thread1.getState());
System.out.println(thread2.getName() + " state: " + thread2.getState());
thread1.start();
thread2.start();
// Sleep briefly to allow threads to start
Thread.sleep(100);
System.out.println(thread1.getName() + " state after starting: " + thread1.getState());
System.out.println(thread2.getName() + " state after starting: " + thread2.getState());
thread1.join();
thread2.join();
System.out.println(thread1.getName() + " state after joining: " + thread1.getState());
System.out.println(thread2.getName() + " state after joining: " + thread2.getState());
}
static class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
try { Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is running iteration " + i);
}
}
}
}
Output:-
Thread state before starting: NEW
Thread state after starting: RUNNABLE
Thread state while sleeping: TIMED_WAITING
Thread state after joining: TERMINATED