Advanced
Multithreading Basics
📂 Phase 5: Advanced Java — Streams, Lambda, Multithreading, DB (Days 22–26) · JavaMultithreading allows a program to execute multiple parts concurrently, improving CPU utilization and responsiveness — especially valuable for tasks like handling many users at once or running background operations.
Creating a Thread — Two Approaches
// Approach 1: Extending Thread
class MyThread extends Thread {
public void run() {
System.out.println("Thread running: " + Thread.currentThread().getName());
}
}
MyThread t1 = new MyThread();
t1.start(); // never call run() directly — start() creates the new thread
// Approach 2: Implementing Runnable (preferred — allows extending other classes too)
class MyTask implements Runnable {
public void run() {
System.out.println("Task running");
}
}
Thread t2 = new Thread(new MyTask());
t2.start();
The Thread Life Cycle
| State | Meaning |
|---|---|
| New | Thread object created, not yet started |
| Runnable | start() called, waiting for CPU time |
| Running | Actively executing |
| Blocked/Waiting | Paused, waiting for a resource or signal |
| Terminated | Finished execution |
Key Thread Methods
Thread.sleep(1000); // pauses current thread for 1000ms
thread.join(); // waits for that thread to finish before continuing
Thread.yield(); // hints the scheduler to let other threads run
The Problem: Shared Data and Race Conditions
When multiple threads access and modify the same data simultaneously without coordination, the result becomes unpredictable — this is a race condition.
class Counter {
int count = 0;
void increment() {
count++; // NOT thread-safe — two threads can interleave here
}
}
Synchronization — The Fix
class Counter {
int count = 0;
synchronized void increment() {
count++; // only one thread can execute this method at a time
}
}
The synchronized keyword ensures only one thread can execute that method (or block) on a given object at a time, preventing race conditions on shared state.
Interview tip: "What is a deadlock?" — A situation where two or more threads are each waiting for a resource the other holds, so neither can proceed. A classic example: Thread A locks Resource 1 and waits for Resource 2, while Thread B locks Resource 2 and waits for Resource 1.