π Java Threads β The Complete Guide to Multithreading in Java
π§² Introduction β Why Learn Java Threads?
Imagine you’re building a responsive app that plays music, downloads files, and allows real-time user interaction β all at the same time. Traditional code runs sequentially, which would make such an app sluggish or even unresponsive. Thatβs where Java Threads and multithreading come into play.
Java Threads enable concurrent execution of two or more parts of a program for maximum CPU utilization. They are fundamental in writing efficient, scalable, and high-performing Java applications β especially in games, web servers, and real-time systems.
β By the end of this guide, you’ll understand:
- What a thread is in Java
- How to create and manage threads
- Thread lifecycle and states
- Thread synchronization & inter-thread communication
- Real-world multithreading use cases
π What Is a Java Thread?
A thread is a lightweight subprocess β the smallest unit of processing. Java supports multithreading via the java.lang.Thread
class and the Runnable
interface.
π Multithreading means executing multiple threads simultaneously to perform multitasking.
π§΅ Creating a Thread in Java
Java provides two ways to create threads:
1οΈβ£ Extending the Thread
Class
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running using Thread class.");
}
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start(); // Start the thread
}
}
β Explanation:
MyThread
extendsThread
, and we override therun()
method with the code we want to execute.start()
triggers therun()
method in a new thread of execution.
2οΈβ£ Implementing the Runnable
Interface
class MyRunnable implements Runnable {
public void run() {
System.out.println("Thread is running using Runnable interface.");
}
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
t1.start(); // Start the thread
}
}
β Explanation:
MyRunnable
implementsRunnable
, which requires arun()
method.- The
Runnable
object is passed to aThread
instance, which is then started.
π‘ Best Practice: Use Runnable
when you want to extend another class, as Java supports only single inheritance.
π Java Thread Lifecycle
A Java thread has five major states:
State | Description |
---|---|
New | Thread object is created but not started |
Runnable | Thread is ready to run and waiting for CPU time |
Running | Thread is executing its run() method |
Blocked/Waiting | Thread is paused and waiting for a resource or signal |
Terminated | Thread has finished executing or was forcefully stopped |
π Use getState()
to check the current thread state.
π§ Java Thread Methods (Essential)
Method | Description |
---|---|
start() | Starts thread and calls run() method |
run() | Entry point for thread execution |
sleep(ms) | Pauses thread for given milliseconds |
join() | Waits for a thread to die |
isAlive() | Checks if thread is alive |
yield() | Hints to scheduler to give other threads a chance |
interrupt() | Interrupts a thread |
β οΈ Warning: Avoid using stop()
as it’s deprecated due to safety concerns.
π Java Thread Synchronization
Multiple threads accessing the same resource can lead to race conditions. Java provides synchronization to handle this.
π Synchronized Block Example
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
β Explanation:
- The
synchronized
keyword ensures that only one thread can accessincrement()
at a time.
π‘ Tip: Synchronize only the critical section of code for better performance.
π Inter-Thread Communication β wait()
, notify()
, notifyAll()
Java threads can communicate using these three methods (must be used in synchronized blocks):
class SharedResource {
boolean flag = false;
synchronized void waitForIt() throws InterruptedException {
while (!flag) {
wait(); // releases lock
}
System.out.println("Thread resumed after notification");
}
synchronized void notifyIt() {
flag = true;
notify(); // wakes up waiting thread
}
}
β Use Case: Producer-consumer problems where one thread waits for another to complete a task.
βοΈ Real-World Use Case: Parallel File Downloads
class FileDownloader extends Thread {
private String file;
FileDownloader(String file) {
this.file = file;
}
public void run() {
System.out.println("Downloading: " + file);
// simulate download time
try { Thread.sleep(2000); } catch (InterruptedException e) {}
System.out.println("Completed: " + file);
}
public static void main(String[] args) {
new FileDownloader("file1.txt").start();
new FileDownloader("file2.txt").start();
new FileDownloader("file3.txt").start();
}
}
β Explanation:
- Each file is downloaded in parallel using a separate thread.
sleep()
simulates time taken to download.
π§° Thread Pools (Advanced Java)
Instead of creating new threads every time (which is costly), use ThreadPoolExecutor or Executors.newFixedThreadPool()
:
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 5; i++) {
int task = i;
executor.execute(() -> {
System.out.println("Executing task " + task);
});
}
executor.shutdown();
}
}
π‘ Benefit: Efficient thread management for large-scale concurrent apps.
π§Ό Best Practices for Java Threads
- β
Use
Runnable
orCallable
with thread pools over rawThread
for production - β
Always
shutdown()
ExecutorService - π Synchronize access to shared resources
- β Avoid using deprecated methods like
stop()
,suspend()
, orresume()
- β
Use
AtomicInteger
,ConcurrentHashMap
, etc., for thread-safe operations
π Summary
Java Threads enable developers to write concurrent, high-performance applications by leveraging multicore processors. From simple parallel tasks to managing thread pools β understanding thread management is key to mastering Java.
π Key Takeaways:
- Learn both
Thread
andRunnable
creation styles - Understand the lifecycle and core methods
- Handle thread safety using synchronization
- Optimize performance using thread pools
βFAQs β Java Threads
β What is the difference between start()
and run()
?
start()
creates a new thread and calls run()
; calling run()
directly does not start a new thread.
β Can we restart a thread in Java?
No, once a thread is terminated, it cannot be restarted. You need to create a new thread object.
β What is a daemon thread?
A daemon thread is a low-priority thread that runs in the background (like garbage collector). Use setDaemon(true)
.
β How to stop a thread safely?
Use a flag (e.g., volatile boolean running = false
) and check it inside run()
to stop execution.
β When should I use ThreadPool?
Use thread pools when you need to execute many short-lived tasks to avoid thread creation overhead.
Share Now :